POJ 1691 Painting A Board(状态压缩DP + 记忆化搜索)
2013-04-06 22:34
507 查看
题意:
有一个矩形框由n个小的矩形组成,现在要把每个矩形涂上一种颜色c(可相同可不同,如下图)。为了保证涂的质量,涂每个小矩阵有一个条件,就是位于它上面,并且与它有连接的小矩形必须先涂好。当然满足条件的同一种颜色可以一起涂,问最少需要多少把刷子(每把刷子一种颜色)。
黑书 146 :平板涂色
思路:
1. 矩形的数量不超过 15,所以自然的联想到利用状态压缩去解决问题,并且为了解决无后效性,还必须增加一维,dp[i][s] 表示以 i 结尾的状态 s 的最小;
2. 首先预处理,矩形 i 上面的矩形编号,为下面的解题作个很好的铺垫;
3. 剩下的工作就是枚举:i 前一个所刷的矩形,思路很简单就不多述了。注意循环的时候 s 放在前面,这样才能保证求得的结果不相互影响;
有一个矩形框由n个小的矩形组成,现在要把每个矩形涂上一种颜色c(可相同可不同,如下图)。为了保证涂的质量,涂每个小矩阵有一个条件,就是位于它上面,并且与它有连接的小矩形必须先涂好。当然满足条件的同一种颜色可以一起涂,问最少需要多少把刷子(每把刷子一种颜色)。
黑书 146 :平板涂色
思路:
1. 矩形的数量不超过 15,所以自然的联想到利用状态压缩去解决问题,并且为了解决无后效性,还必须增加一维,dp[i][s] 表示以 i 结尾的状态 s 的最小;
2. 首先预处理,矩形 i 上面的矩形编号,为下面的解题作个很好的铺垫;
3. 剩下的工作就是枚举:i 前一个所刷的矩形,思路很简单就不多述了。注意循环的时候 s 放在前面,这样才能保证求得的结果不相互影响;
#include <iostream> #include <algorithm> using namespace std; const int INFS = 0x3FFFFFFF; struct POINT { int x1, y1, x2, y2; int color; } rect[20] ; int up[20], dp[15][1<<15]; bool judge(int i, int j) { // whether j is upper to i if (rect[j].x2 != rect[i].x1) return false; if (rect[j].y2 <= rect[i].y1) return false; if (rect[j].y1 >= rect[i].y2) return false; return true; } int workout(int n) { for (int i = 0; i < n; i++) { up[i] = 0; for (int j = 0; j < n; j++) if (judge(i, j)) up[i] |= (1<<j); } int ENDS = (1<<n) - 1; for (int i = 0; i < n; i++) for (int s = 0; s <= ENDS; s++) dp[i][s] = INFS; for (int i = 0; i < n; i++) if (up[i] == 0) dp[i][1<<i] = 1; for (int s = 0; s <= ENDS; s++) { for (int i = 0; i < n; i++) { if (s & (1<<i)) continue; if ((s & up[i]) != up[i]) continue; for (int j = 0; j < n; j++) { if (!(s & (1<<j))) continue; int now = s | (1<<i); int value = dp[j][s]; if (rect[i].color != rect[j].color) value += 1; dp[i][now] = min(dp[i][now], value); } } } int ans = INFS; for (int i = 0; i < n; i++) ans = min(ans, dp[i][ENDS]); return ans; } int main() { int cases; scanf("%d", &cases); while (cases--) { int n; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d%d%d%d%d", &rect[i].x1, &rect[i].y1, &rect[i].x2, &rect[i].y2, &rect[i].color); printf("%d\n", workout(n)); } return 0; }
相关文章推荐
- POJ 1691 Painting a Board(状态压缩DP)
- poj 1691 Painting a Board(状态压缩DP)
- POJ - 1691 Painting A Board (状态压缩 + 暴力)
- poj - 1691 - Painting A Board(状态压缩dp)
- pku 1691 Painting A Board 状态压缩dp
- pku 1691 Painting A Board(据说可以用状态压缩DP)
- Painting A Board --POJ 1691
- poj 1691 状态压缩DP
- poj 炮兵阵地 状态压缩DP + 位运算
- poj&nbsp;1691&nbsp;Painting&nbsp;A&nbsp;Board
- poj_1691 Painting A Board(dfs+拓扑)
- [POJ 1691]Painting A Board[DFS][排序]
- poj1691 Painting A Board
- poj 1691 Painting A Board
- POJ 1351 Number of Locks (记忆化搜索 状态压缩)
- POJ1691-Painting A Board
- 【poj 1691】Painting A Board 题意&题解&代码(C++)
- poj 1691 Painting A Board
- poj 1691 Painting A Board 拓扑序+dfs
- poj 1691 Painting A Board