poj1691——Painting A Board

来源:互联网 发布:初学c语言 编辑:程序博客网 时间:2024/05/16 12:08

题目大意:给一个包含N个矩形的板子上色,每个矩形的颜色已经确定,给一个矩形上色时,必须满足它上方的所有矩形已经上色结束,一个刷子只能用一次且涂满整个矩形,问最少需要多少个刷子

输入:case个数M (1 <= M <= 10)

           第i个case的矩形个数N(1<=N<=15)

           N个矩形的描述(左上角坐标y  x  右下角坐标y  x(坐标0~99横坐标x纵坐标y)  颜色代码(代码1~20))(每个占一行)

输出:需要的最小刷子个数

分析:dfs+dp

           先输入建图,存储好矩形i上方相邻的矩形j的编号,然后依次对矩形进行dfs,判断它上方是否已涂,若满足,则涂这个矩形,涂时判断刷子要不要+1,然后继续dfs下一个矩形

代码:转载自http://blog.csdn.net/tsaid/article/details/6841823

  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. #define N 16  
  5. int m, n, ans;  
  6. int up[N][N], mark[N]; //up[i][j]表示矩形i上方相邻的第j块(j从1起)矩形的编号。mark用来记录某一个矩形是否已经被涂色  
  7.   
  8. struct Rectangle  
  9. {  
  10.     int x1, x2, y1, y2, color;  
  11. } rec[N];  
  12.   
  13. bool check ( int i, int j )  
  14. {  
  15.     if ( rec[i].y2 != rec[j].y1 ) return false;//判断是否直接相邻
  16.     if ( rec[i].x2 <= rec[j].x1 ) return false;//判断i的最右侧是否在j的最左侧的左边
  17.     if ( rec[i].x1 >= rec[j].x2 ) return false;//判断i的最左侧是否在j的最右侧的右边
  18.     return true;  
  19. }  
  20.   
  21. void build_map()  
  22. {  
  23.     for ( int i = 1; i <= n; i++ )  
  24.     {  
  25.         for ( int j = 1; j <= n; j++ )  
  26.             if ( check(i,j) )  
  27.                 up[j][++up[j][0]] = i;//i在j上方相邻  
  28.     }  
  29. }  
  30.   
  31. void dfs ( int pick, int color, int cnt )  //刷子个数  颜色代码  矩形个数
  32. {  
  33.     if ( pick >= ans )  
  34.         return;  
  35.     if ( cnt == n )  
  36.     {  
  37.         ans = pick;  
  38.         return;  
  39.     }  
  40.   
  41.     int i, j, flag;  
  42.     for ( i = 1; i <= n; i++ )  
  43.     {  
  44.         if ( mark[i] ) continue// 若矩形i已经涂色,直接进入下次循环  
  45.   
  46.         flag = 1;  
  47.         for ( j = 1; j <= up[i][0]; j++ )  
  48.             if ( ! mark[ up[i][j] ] )  // 若i上面的矩形中有没被涂色的,则flag = false  
  49.             {  
  50.                 flag = 0; break;  
  51.             }  
  52.   
  53.         if ( flag )  
  54.         {  
  55.             mark[i] = 1; // 标记i已经被涂色  
  56.             if ( rec[i].color == color )  
  57.                 dfs ( pick, color, cnt+1);  
  58.             else  
  59.                 dfs ( pick+1, rec[i].color, cnt+1);  
  60.             mark[i] = 0;  
  61.         }  
  62.     }  
  63. }  
  64.   
  65.   
  66. int main()  
  67. {  
  68.     cin >> m;  
  69.     while ( m-- )  
  70.     {  
  71.         cin >> n;  
  72.         for ( int i = 1; i <= n; i++ )  
  73.             cin >> rec[i].y1 >> rec[i].x1 >> rec[i].y2 >> rec[i].x2 >> rec[i].color;  
  74.   
  75.         memset(up,0,sizeof(up));  
  76.         memset(mark,0,sizeof(mark));  
  77.         ans = 999999999;  
  78.   
  79.         build_map();  
  80.         dfs ( 0, 0, 0 );  
  81.         cout << ans << endl;  
  82.     }  
  83.     return 0;  
  84. }

原创粉丝点击