POJ 1185 炮兵阵地(状态压缩DP)
2013-04-05 22:00
423 查看
题意:
求最大的炮兵摆放数量,并且使他们之间不相互误伤。
NOI 01 的题目。
思路:
1. 和 POJ 1038 类似,把行看成是一个整体,每一种摆放代表着一种状态,r-2, r-1 行的状态决定着 r 行的状态;
2. 本题状态比较稀疏,所以提前处理下炮兵的摆放无意是比较好的选择,由于没两个炮兵之间至少相距为 2,利用这个把每一行的炮兵可能摆放情况存放起来;
3. dp[r][i][j] 表示第 r 行的状态为 i 且第 r-1 行的状态为 j 时,所能摆放的最大炮兵数量,同时还需要枚举 r-2 行的炮兵摆放情况;
4. 最终有状态转移方程: dp[r][i][j] = max(dp[r][i][j], dp[r-1][j][k] + men[i]); 并且要求 dp[r-1][j][k] 存在,且 r 行能保证能摆放 i 状态;
5. 有了 POJ 1038 和 POJ 1185 的积累,我想以后做此类基于摆放的状态压缩 DP 应该能够有个比较清晰的思路了。
求最大的炮兵摆放数量,并且使他们之间不相互误伤。
NOI 01 的题目。
思路:
1. 和 POJ 1038 类似,把行看成是一个整体,每一种摆放代表着一种状态,r-2, r-1 行的状态决定着 r 行的状态;
2. 本题状态比较稀疏,所以提前处理下炮兵的摆放无意是比较好的选择,由于没两个炮兵之间至少相距为 2,利用这个把每一行的炮兵可能摆放情况存放起来;
3. dp[r][i][j] 表示第 r 行的状态为 i 且第 r-1 行的状态为 j 时,所能摆放的最大炮兵数量,同时还需要枚举 r-2 行的炮兵摆放情况;
4. 最终有状态转移方程: dp[r][i][j] = max(dp[r][i][j], dp[r-1][j][k] + men[i]); 并且要求 dp[r-1][j][k] 存在,且 r 行能保证能摆放 i 状态;
5. 有了 POJ 1038 和 POJ 1185 的积累,我想以后做此类基于摆放的状态压缩 DP 应该能够有个比较清晰的思路了。
#include <iostream> #include <algorithm> using namespace std; int row, col; int state[60], cnt, men[60], mapstate[110]; bool grid[110][12]; int dp[2][60][60]; bool judge(int s) { if (s & (s<<1)) return false; if (s & (s<<2)) return false; return true; } int calcmen(int s) { int ans = 0; while (s) { ans += 1; s &= (s-1); } return ans; } void initstate(int endstate) { cnt = 0; for (int s = 0; s < endstate; s++) { if (judge(s)) { state[cnt] = s; men[cnt] = calcmen(s); cnt += 1; } } } int solvedp() { memset(dp[0], -1, sizeof(dp[0])); for (int i = 0; i < cnt; i++) { if (mapstate[0] & state[i]) continue; dp[0][i][0] = men[i]; } int T1 = 1, T2 = 0; for (int r = 1; r < row; r++) { T1 ^= 1, T2 ^= 1; memset(dp[T2], -1, sizeof(dp[0])); for (int i = 0; i < cnt; i++) { if (state[i] & mapstate[r]) continue; for (int j = 0; j < cnt; j++) { if ((state[i] & state[j]) || (state[j] & mapstate[r-1])) continue; for (int k = 0; k < cnt; k++) { if ((state[i] & state[k]) || (state[k] & state[j])) continue; if (dp[T1][j][k] != -1) dp[T2][i][j] = max(dp[T2][i][j], dp[T1][j][k]+men[i]); } } } } int ans = -1; for (int i = 0; i < cnt; i++) for (int j = 0; j < cnt; j++) ans = max(ans, dp[T2][i][j]); return ans; } int main() { scanf("%d%d", &row, &col); for (int i = 0; i < row; i++) { char s[20]; scanf("%s", s); mapstate[i] = 0; for (int j = 0; j < col; j++) { mapstate[i] <<= 1; mapstate[i] |= s[j] == 'H' ? 1 : 0; } } initstate(1<<col); printf("%d\n", solvedp()); return 0; }
相关文章推荐
- poj 1185 炮兵阵地(状态压缩dp)
- POJ1185炮兵阵地(DP状态压缩)
- POJ1185 炮兵阵地 状态压缩DP
- poj 1185 炮兵阵地 (状态压缩dp)
- POJ 1185炮兵阵地(状态压缩dp)
- POJ 1185 炮兵阵地(状态压缩dp)
- poj 1185 状态压缩dp-炮兵阵地
- POJ 1185 炮兵阵地[状态压缩DP]
- POJ 1185 炮兵阵地 (状态压缩dp)
- POJ 1185 炮兵阵地(状态压缩DP)
- POJ 1185 炮兵阵地(状态压缩DP)
- POJ1185炮兵阵地(状态压缩DP)
- 【DP|状态压缩+预处理】POJ-1185 炮兵阵地
- poj 1185 && NYOJ 85 炮兵阵地(状态压缩dp)
- POJ 1185 炮兵阵地(状态压缩dp)
- POJ 1185 炮兵阵地 状态压缩DP
- poj1185 炮兵阵地 状态压缩dp
- POJ 1185 炮兵阵地(状态压缩DP)
- 状态压缩DP-炮兵阵地(POJ 1185)
- poj 1185 炮兵阵地 [经典状态压缩DP]