Description
The CE digital company has built an Automatic Painting Machine (APM) to paint a flat board fully covered by adjacent non-overlapping rectangles of different sizes each with a predefined color.
To color the board, the APM has access to a set of brushes. Each brush has a distinct color C. The APM picks one brush with color C and paints all possible rectangles having predefined color C with the following restrictions:
To avoid leaking the paints and mixing colors, a rectangle can only be painted if all rectangles immediately above it have already been painted. For example rectangle labeled F in Figure 1 is painted only after rectangles C and D are painted. Note that each rectangle must be painted at once, i.e. partial painting of one rectangle is not allowed.
You are to write a program for APM to paint a given board so that the number of brush pick-ups is minimum. Notice that if one brush is picked up more than once, all pick-ups are counted.

To color the board, the APM has access to a set of brushes. Each brush has a distinct color C. The APM picks one brush with color C and paints all possible rectangles having predefined color C with the following restrictions:
To avoid leaking the paints and mixing colors, a rectangle can only be painted if all rectangles immediately above it have already been painted. For example rectangle labeled F in Figure 1 is painted only after rectangles C and D are painted. Note that each rectangle must be painted at once, i.e. partial painting of one rectangle is not allowed.
You are to write a program for APM to paint a given board so that the number of brush pick-ups is minimum. Notice that if one brush is picked up more than once, all pick-ups are counted.
Input
The first line of the input file contains an integer M which is the number of test cases to solve (1 <= M <= 10). For each test case, the first line contains an integer N, the number of rectangles, followed by N lines describing the rectangles. Each rectangle R is specified by 5 integers in one line: the y and x coordinates of the upper left corner of R, the y and x coordinates of the lower right corner of R, followed by the color-code of R.
Note that:
Note that:
- Color-code is an integer in the range of 1 .. 20.
- Upper left corner of the board coordinates is always (0,0).
- Coordinates are in the range of 0 .. 99.
- N is in the range of 1..15.
Output
One line for each test case showing the minimum number of brush pick-ups.
Sample Input
1 7 0 0 2 2 1 0 2 1 6 2 2 0 4 2 1 1 2 4 4 2 1 4 3 6 1 4 0 6 4 1 3 4 6 6 2
Sample Output
3
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define maxn 55 #define inf 0x3f3f3f3f int first[maxn],vv[maxn],nxt[maxn],rudu[maxn]; bool vis[maxn]; int e = 0,ans,n; struct REC { int x1,y1,x2,y2,col; }rec[maxn]; void addEdge(int u,int v) { rudu[v]++; vv[e] = v; nxt[e] =first[u]; first[u] = e++; } bool Judge(int u,int v) { if(((rec[v].x1 <= rec[u].x1 && rec[v].x2 > rec[u].x1) || (rec[v].x1 < rec[u].x2 && rec[v].x2 >= rec[u].x2) || (rec[v].x1 >= rec[u].x1 && rec[v].x2 <= rec[u].x2)) && (rec[v].y2 > rec[u].y1)) return 1; return 0; } void dfs(int u,int res,int used) { if(used >= ans) return; if(res == 0) { ans = used; return; } bool flag = false; int pos; for(int i = first[u];i != -1;i = nxt[i]) { int v = vv[i]; if(vis[v]) continue; rudu[v]--; } for(int i = 1;i <= n;i++) { if((!vis[i]) && (rec[i].col == rec[u].col) && (rudu[i] == 0)) { flag = true; pos = i; break; } } if(flag) { vis[pos] = 1; dfs(pos,res-1,used); vis[pos] = 0; } else { for(int i = 1;i <= n;i ++) { if(vis[i]) continue; if(rudu[i] == 0) { vis[i] = 1; dfs(i,res-1,used+1); vis[i] = 0; } } } for(int i = first[u];i != -1;i = nxt[i]) { int v = vv[i]; rudu[v]++; } } int main() { //freopen("in.txt","r",stdin); int t; scanf("%d",&t); while(t--) { e = 0; scanf("%d",&n); memset(rudu,0,sizeof(rudu)); memset(first,-1,sizeof(first)); for(int i = 1;i <= n;i++) { scanf("%d%d%d%d%d",&rec[i].y1,&rec[i].x1,&rec[i].y2,&rec[i].x2,&rec[i].col); } for(int i = 1;i <= n;i++) { for(int j = 1;j <= n;j++) { if(i == j) continue; if(Judge(i,j)) addEdge(i,j); } }到这里就把所有矩形的上下关系都确定好了。接下来就是深搜了。 ans = inf; for(int i = 1;i <= n;i++) { memset(vis,0,sizeof(vis)); if(rudu[i] == 0) { vis[i] = 1; dfs(i,n-1,1); } } printf("%d\n",ans); } return 0; }