题意 : 看了好长时间终于看懂题目了,将一个大矩形划分成若干小矩形,告诉你每个小矩形的左上角那个点和右下角那个点的坐标,告诉你这个小矩形要涂的颜色,每个颜色对应一个刷子,问你最少要使用几次刷子。因为你要刷一个矩形之前,必须把这个矩形上方与之直接相邻的所有矩形先刷掉才能刷这个,如果你先用了红色的刷子,然后又用了蓝色的刷子,最后又用了红色的刷子,这算是3次使用而不是两次,样例中,用红色刷B所以D也可以刷了,用蓝色先刷A,然后可以刷C,因为B刷了所以E也可以刷了,最后换刷子把剩下的刷掉,总共三次。
思路 : 这个题可以用DFS也可以用状压DP,我用的DFS,因为没压出来,,,,,,,这里有分析,链接1,链接2。先将每个矩形看成一个点,然后如果存在上下关系的话,下边那个点的入度+1,先找入度为0的点开始染色,如果这个点已经染掉了的话,那它下边的点入度要减1.。。。。。。。
1 //1691 2 #include <stdio.h> 3 #include <string.h> 4 #include <iostream> 5 6 using namespace std ; 7 8 struct rectangle 9 { 10 int lx,ly ; 11 int rx,ry ; 12 int R ; 13 } rec[16]; 14 int degree[16] ; 15 bool mapp[16][16],vis[16] ; 16 int M ,n; 17 int cnt ; 18 19 void build() 20 { 21 memset(mapp,false,sizeof(mapp)) ; 22 memset(degree,0,sizeof(degree)) ; 23 memset(vis,false,sizeof(vis)) ; 24 for(int i = 0 ; i < n ; i++) 25 { 26 for(int j = 0 ; j < n ; j++) 27 { 28 if(i == j) continue ; 29 else 30 { 31 if(rec[i].ly == rec[j].ry && !(rec[i].rx < rec[j].lx || rec[j].rx < rec[i].lx)) 32 { 33 mapp[i][j] = true ; 34 degree[i] ++ ; 35 } 36 } 37 } 38 } 39 } 40 41 void DFS(int r,int ans,int step) 42 { 43 if(ans > cnt) return ; 44 if(step == n) 45 { 46 cnt = ans ; 47 return ; 48 } 49 for(int i = 0 ; i < n ; i++) 50 { 51 if(!vis[i] && degree[i] == 0) 52 { 53 vis[i] = true ; 54 for(int j = 0 ; j < n ; j++) 55 if(mapp[j][i]) 56 degree[j] -- ; 57 if(rec[i].R == r ) DFS(r,ans,step+1) ; 58 else DFS(rec[i].R,ans + 1,step+1) ; 59 vis[i] = false ; 60 for (int j = 0; j < n; j++) 61 { 62 if (mapp[j][i]) degree[j]++; 63 } 64 } 65 } 66 } 67 int main() 68 { 69 scanf("%d",&M) ; 70 while(M--) 71 { 72 scanf("%d",&n) ; 73 for(int i = 0 ; i < n ; i++) 74 scanf("%d %d %d %d %d",&rec[i].ly,&rec[i].lx,&rec[i].ry,&rec[i].rx,&rec[i].R) ; 75 build() ; 76 cnt = 9999999 ; 77 DFS(0,0,0) ; 78 printf("%d\n",cnt) ; 79 } 80 return 0 ; 81 }
来源:https://www.cnblogs.com/luyingfeng/p/3773610.html