poj 1691 Painting A Board (DFS/状态压缩DP)

    http://poj.org/problem?id=1691
/*
题解: 将每个矩形看成一个点,点A在点B的上方 则b的入度加1,进行拓扑构图 标记 ,每次搜索时搜入读为零的点 构图时少考虑的一种情况 wa 汗。。。。。。。 */ #include<stdio.h> #include<string.h> #define max 999999 #define maxn 2000 struct node { int xl,yl,xr,yr; int c; }p[maxn]; int map[20][20],in[20],n,ans,vis[20]; void build() { int i,j; memset(map,0,sizeof(map)); memset(in,0,sizeof(in)); memset(vis,0,sizeof(vis)); for(i=0;i<n;i++) { for(j=0;j<n;j++) { if(i==j)continue; if(p[i].yr==p[j].yl&&!(p[j].xl>=p[i].xr||p[j].xr<=p[i].xl))//连边条件 { map[i][j]=1; in[j]++; } } } } void DFS(int pre,int num,int sum) { if(ans==1)return ; int i,j; if(num==n) { if(ans>sum)ans=sum; return ; } for(i=0;i<n;i++) { if(in[i]==0&&!vis[i]) { vis[i]=1; for(j=0;j<n;j++) { if(map[i][j])in[j]--; } if(p[i].c==pre) DFS(p[i].c,num+1,sum); else DFS(p[i].c,num+1,sum+1); vis[i]=0; for(j=0;j<n;j++) { if(map[i][j])in[j]++; } } } } int main() { int t,i,j; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=0;i<n;i++) { scanf("%d%d%d%d%d",&p[i].yl,&p[i].xl,&p[i].yr,&p[i].xr,&p[i].c); } build(); /*for(i=0;i<n;i++) { for(j=0;j<n;j++) printf("%d ",map[i][j]); printf("\n"); }*/ //for(i=0;i<n;i++)printf("%d ",in[i]); ans=max; DFS(-1,0,0); printf("%d\n",ans); } }

 

状态压缩DP
1
#include<stdio.h> 2 #include<string.h> 3 #define inf 999999 4 #define min(x,y) x<y?x:y 5 #define maxn 25 6 int dp[1<<16][20];//dp[s][j]表示到达 使得最后一个 图色的矩形是j,到达s状态所用的次数 7 int m[maxn]; 8 struct node 9 { 10 int xl,yl,xr,yr,c; 11 }p[maxn]; 12 int n; 13 bool check(int i,int j) 14 { 15 if(p[i].yr!=p[j].yl)return false; 16 if(p[i].xr<=p[j].xl)return false; 17 if(p[i].xl>=p[j].xr)return false; 18 return true; 19 20 21 } 22 void build() 23 { 24 int i,j; 25 memset(m,0,sizeof(m)); 26 for(i=0;i<n;i++) 27 { 28 for(j=0;j<n;j++) 29 { 30 if(check(i,j)) 31 m[j]|=(1<<i);//将在j上面的矩形标记 32 } 33 } 34 } 35 void get_dp() 36 { 37 int i,j,s; 38 int state=1<<n; 39 for(i=0;i<state;i++) 40 { 41 for(j=0;j<n;j++) 42 { 43 dp[i][j]=inf; 44 } 45 } 46 47 for(i=0;i<n;i++) 48 if(m[i]==0)dp[1<<i][i]=1; 49 50 51 for(s=0;s<state;s++) 52 { 53 for(i=0;i<n;i++) 54 { 55 if(s&(1<<i))continue;//已经图过色了 56 if((s&m[i])!=m[i])continue;//他的上面还没图完 57 for(j=0;j<n;j++) 58 { 59 if((s&(1<<j))==0)continue;//j还没图色 60 int t=dp[s][j]; 61 int x=1<<i; 62 if(p[i].c!=p[j].c)t++; 63 dp[x+s][i]=min(dp[s+x][i],t); 64 65 } 66 } 67 68 69 } 70 71 int ans=inf; 72 for(j=0;j<n;j++) 73 { 74 ans=min(ans,dp[state-1][j]); 75 76 } 77 printf("%d\n",ans); 78 } 79 int main() 80 { 81 int t; 82 scanf("%d",&t); 83 while(t--) 84 { 85 scanf("%d",&n); 86 for(int i=0;i<n;i++) 87 { 88 scanf("%d%d%d%d%d",&p[i].yl,&p[i].xl,&p[i].yr,&p[i].xr,&p[i].c); 89 } 90 build(); 91 get_dp(); 92 } 93 }

 

你可能感兴趣的:(paint)