思路为dpi表示涂色状态为i是最小花费步数,然后枚举所有可能转移的颜色刷表。
#include<bits/stdc++.h>
#define int long long
#define N 18
#define M 25
#define INF 1e18
using namespace std;
struct node{
int x,y,xx,yy,col;
}e[N];
int n,m,dp[1<<N],ned[N][N],c[M][M],qwq;
signed main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++){
cin>>e[i].y>>e[i].x>>e[i].yy>>e[i].xx>>e[i].col;
c[e[i].col][++c[e[i].col][0]]=i;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(e[j].yy+1==e[i].y&&
((e[j].x>=e[i].x&&e[j].x<=e[i].xx)||
(e[j].xx>=e[i].x&&e[j].xx<=e[i].xx))
){
ned[i][++ned[i][0]]=j;
}
}
}
for(int i=0;i<(1<<n);i++) dp[i]=INF;
dp[0]=0;
for(int i=0;i<(1<<n);i++){
for(int j=1;j<=20;j++){
qwq=0;
for(int k=1;k<=c[j][0];k++){
int y=c[j][k],fl=1;
for(int q=1;q<=ned[y][0];q++){
if((1ll<<(ned[y][q]-1))&i) continue;
fl=0;break;
}
if(fl) qwq+=(1ll<<(y-1));
}
dp[i|qwq]=min(dp[i|qwq],dp[i]+1);
}
}
cout<<dp[(1<<n)-1];
return 0;
}