博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ - 1185 炮兵阵地 (状态压缩)
阅读量:5033 次
发布时间:2019-06-12

本文共 2733 字,大约阅读时间需要 9 分钟。

题目大意:中文题目就不多说大意了

解题思路:

1.每行最多仅仅有十个位置,且不是山地就是平原,那么就能够用1表示山地,0表示平原,将每一行的状态进行压缩了

2.接着找出每行能放炮兵的状态。先不考虑其它行放炮兵和该行的山地对其造成的影响,枚举出全部的状态。并记录每一个状态下放的炮兵数量

在上述情况下放炮兵。仅仅须要考虑同行的炮兵是否会相互攻击就能够了,那仅仅须要推断他的左边第一个位置是否有炮兵和左边第二个位置是否有炮兵就可以

3.接着进行dp,由于影响因素有两个。一个是上一行的状态,还有一个是上两行的状态,所以设dp[row][i][j]为第row行,放置状态为i,第row-1行,放置状态为j的情况下所能放的最多炮兵数量

可得到转移方程,在前两行不影响该行放置的
dp[row][i][j] = max(dp[row][i][j], dp[row-1][j][k] + i状态下能放置的炮兵数)

參考了这位大神的代码,写得很得具体

#include
#include
#include
using namespace std;#define maxn 110#define maxm 20#define maxs 70int R, C, cnt;char str[15];int row[maxn], num[maxn], statu[maxn];int dp[maxn][maxs][maxs];void input() { memset(row, 0, sizeof(row)); for(int i = 0; i < R; i++) { scanf("%s", str); for(int j = 0; j < C; j++) if(str[j] == 'H') row[i] += (1 << j); }}void init_statu() { memset(num, 0, sizeof(num)); cnt = 0; for(int i = 0; i < (1 << C); i++) { if((i & (i << 1)) || (i & (i << 2))) continue; int t = i; while(t) { num[cnt] += (t & 1); t >>= 1; } statu[cnt++] = i; }}void init_DP() { memset(dp, 0, sizeof(dp)); for(int i = 0; i < cnt; i++) { if(statu[i] & row[0]) continue; dp[0][i][0] = num[i]; } for(int i = 0; i < cnt; i++) { if(statu[i] & row[1]) continue; for(int j = 0; j < cnt; j++) { if(statu[j] & row[0]) continue; if(statu[i] & statu[j]) continue; dp[1][i][j] = max(dp[1][i][j], dp[0][j][0] + num[i]); } }}int solve() { for(int r = 2; r < R; r++) { for(int i = 0; i < cnt; i++) { if(statu[i] & row[r]) continue; for(int j = 0; j < cnt; j++) { if(statu[j] & row[r - 1]) continue; if(statu[i] & statu[j]) continue; for(int k = 0; k < cnt; k++) { if(statu[k] & statu[j]) continue; if(statu[k] & statu[i]) continue; if(statu[k] & row[r - 2]) continue; dp[r][i][j] = max(dp[r][i][j], dp[r - 1][j][k] + num[i]); } } } } int ans = 0; for(int i = 0; i < cnt; i++) for(int j = 0; j < cnt; j++) ans = max(ans, dp[R-1][i][j]); return ans;}int main() { while(scanf("%d%d", &R, &C) != EOF) { input(); init_statu(); init_DP(); printf("%d\n", solve()); } return 0;}

转载于:https://www.cnblogs.com/mengfanrong/p/5186980.html

你可能感兴趣的文章
四六级作文常见错误解析(转载)
查看>>
Tomcat
查看>>
./是当前目录 ../是当前的上一级目录。上上级就是../../一般绝对路径时候常用...
查看>>
树的递归与非递归遍历方法
查看>>
每天一个Linux命令(6):rmdir命令
查看>>
oracle连接的三个配置文件(转)
查看>>
RecyclerView 局部刷新(获取viewHolder 去刷新)
查看>>
PHP表单(get,post)提交方式
查看>>
使用vbs或者bat脚本修改IE浏览器安全级别和选项
查看>>
Silverlight入门
查看>>
LeetCode 895. Maximum Frequency Stack
查看>>
一个简单的日志函数C++
查看>>
Java 8 中如何优雅的处理集合
查看>>
Java操作Excel和Word
查看>>
Oracle 体系结构之ORACLE物理结构
查看>>
ORA-12538: TNS: no such protocol adapter
查看>>
盒子模型
查看>>
局域网协议
查看>>
[HNOI2012]永无乡 线段树合并
查看>>
SqlServer之Convert 函数应用格式化日期(转)
查看>>