POJ 1038 Bugs Integrated(状态压缩DP)
2013-04-05 19:43
330 查看
题意:
将 2*3 的芯片嵌入 n*m 的单位尺寸模板中,模板上面有一些坏点将被标记出,求最大的芯片数量。
黑书 138 页的例题, CEOI 2002;
思路:
1. 由于 m <= 10,所以可以针对每一行看成一个整体,根据情况来产生一个状态,首先肯定是枚举当前行的状态,来产生下一行的状态了,时间复杂度为O(nm3m);
2. 递推的过程中,因为是由一个已知状态,转移到多个未知状态,如何产生这多个未知状态?这里采用 DFS 的方式,提供了 2 个数组 Q,随时存储和恢复状态;
3. Q[1][i] 代表当前行的摆放情况, Q[0][i] 代表上一行的摆放情况。并且值为 0,1,2 如黑书上面描述的一样。采用 3 进制表示法,因为如果用 2 个二进制位表示,总共可能会达到 20 位,这样会产生很大的内存浪费;
4. 因为当前行的状态以及值,都是由上一行的情况转移过来的,所以利用滚动数组,可以有效的节省内存,注意每次要置 -1 即可。
将 2*3 的芯片嵌入 n*m 的单位尺寸模板中,模板上面有一些坏点将被标记出,求最大的芯片数量。
黑书 138 页的例题, CEOI 2002;
思路:
1. 由于 m <= 10,所以可以针对每一行看成一个整体,根据情况来产生一个状态,首先肯定是枚举当前行的状态,来产生下一行的状态了,时间复杂度为O(nm3m);
2. 递推的过程中,因为是由一个已知状态,转移到多个未知状态,如何产生这多个未知状态?这里采用 DFS 的方式,提供了 2 个数组 Q,随时存储和恢复状态;
3. Q[1][i] 代表当前行的摆放情况, Q[0][i] 代表上一行的摆放情况。并且值为 0,1,2 如黑书上面描述的一样。采用 3 进制表示法,因为如果用 2 个二进制位表示,总共可能会达到 20 位,这样会产生很大的内存浪费;
4. 因为当前行的状态以及值,都是由上一行的情况转移过来的,所以利用滚动数组,可以有效的节省内存,注意每次要置 -1 即可。
#include <iostream> #include <algorithm> using namespace std; bool grid[160][12]; int row, col, Q[2][12], dp[2][60000]; void backstate(int s, int f[]) { for (int i = 0; i < col; i++) { f[i] = s % 3; s /= 3; } } int getstate(int f[]) { int ans = 0; for (int i = col-1; i >= 0; i--) { ans *= 3; ans += f[i]; } return ans; } int T1, T2; void dfs(int i, int count, int state) { if (i > col - 1) return; if (i+2 < col && Q[1][i] == 0 && Q[1][i+1] == 0 && Q[1][i+2] == 0) { Q[1][i] = Q[1][i+1] = Q[1][i+2] = 2; int now = getstate(Q[1]); dp[T2][now] = max(dp[T2][now], count+1); dfs(i+3, count+1, now); Q[1][i] = Q[1][i+1] = Q[1][i+2] = 0; } if (i+1 < col && Q[1][i] == 0 && Q[1][i+1] == 0 && Q[0][i] == 0 && Q[0][i+1] == 0) { Q[1][i] = Q[1][i+1] = 2; int now = getstate(Q[1]); dp[T2][now] = max(dp[T2][now], count+1); dfs(i+2, count+1, now); Q[1][i] = Q[1][i+1] = 0; } dp[T2][state] = max(dp[T2][state], dp[T1][getstate(Q[0])]); dfs(i+1, count, state); } int solvedp() { int endstate = 1; for (int i = 0; i < col; i++) endstate *= 3; for (int i = 0; i < col; i++) Q[1][i] = grid[0][i] ? 2 : 1; memset(dp[0], -1, sizeof(dp[0])); dp[0][getstate(Q[1])] = 0; T1 = 1, T2 = 0; for (int i = 1; i < row; i++) { T1 ^= 1, T2 ^= 1; memset(dp[T2], -1, sizeof(dp[0])); for (int s = 0; s < endstate; s++) { if (dp[T1][s] == -1) continue; backstate(s, Q[0]); for (int j = 0; j < col; j++) { Q[1][j] = grid[i][j] ? 2 : Q[0][j]-1; if (Q[1][j] < 0) Q[1][j] = 0; } dfs(0, dp[T1][s], getstate(Q[1])); } } int ans = -1; for (int s = 0; s < endstate; s++) ans = max(ans, dp[T2][s]); return ans; } int main() { int cases; scanf("%d", &cases); while (cases--) { int tag; scanf("%d%d%d", &row, &col, &tag); memset(grid, false, sizeof(grid)); for (int i = 0; i < tag; i++) { int x, y; scanf("%d%d", &x, &y); grid[x-1][y-1] = true; } printf("%d\n", solvedp()); } return 0; }
相关文章推荐
- Poj1038 Bugs Integrated, Inc.【状态压缩DP】
- poj 1038 Bugs Integrated, Inc. __dp状态压缩
- POJ 1038 Bugs Integrated, Inc. 状态压缩DP
- poj 1038 Bugs Integrated, Inc. 状态压缩dp
- poj 1038 - Bugs Integrated, Inc.(状态压缩dp)
- CEOI 2002, POJ 1038 Bugs Integrated, Inc. 状态压缩 DP
- poj 1038 Bugs Integrated, Inc. __dp状态压缩
- poj 1038 Bugs Integrated, Inc. 三进制状态压缩 DFS 滚动数组
- POJ 1038 Bugs Integrated, Inc. (状态dp)
- POJ 1038 - Bugs Integrated, Inc. 三进制状态DP
- POJ 1038 Bugs Integrated, Inc. 状态压缩dp+3进制枚举
- poj 1038 Bugs Integrated, Inc.(动态规划状态压缩)
- 【DP,状态压缩】PKU-1038-Bugs Integrated, Inc.
- POJ 1038 Bugs Integrated, Inc.(状态压缩)
- POJ--1038--Bugs Integrated, Inc.--状态DP
- POJ 1038 Bug Integrated Inc(状态压缩DP)
- POJ 1038 状态压缩dp
- poj 1038 Bugs Integrated, Inc.(状压dp)
- poj 1038 状态压缩dp
- POJ1038 - Bugs Integrated, Inc.(状态压缩DP)