POJ 1691 Painting A Board(DFS)

链接

题意 : 看了好长时间终于看懂题目了,将一个大矩形划分成若干小矩形,告诉你每个小矩形的左上角那个点和右下角那个点的坐标,告诉你这个小矩形要涂的颜色,每个颜色对应一个刷子,问你最少要使用几次刷子。因为你要刷一个矩形之前,必须把这个矩形上方与之直接相邻的所有矩形先刷掉才能刷这个,如果你先用了红色的刷子,然后又用了蓝色的刷子,最后又用了红色的刷子,这算是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 }
View Code

 

你可能感兴趣的:(paint)