Poj 1185 炮兵阵地 状态压缩
2014-10-14 15:22
148 查看
题目链接:http://poj.org/problem?id=1185
题目大意:
在N*M的网格地图上部署炮兵部队。地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图。在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队);一支炮兵部队在地图上的攻击范围如图中黑色区域所示:
![](http://poj.org/images/1185_1.jpg)
如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域。炮兵的攻击范围不受地形的影响。
现在,如何部署炮兵部队,使得任何一支炮兵部队都不在其他支炮兵部队的攻击范围内,在整个地图区域内最多能够摆放多少我军的炮兵部队。
解题思路:由于每行最多只有10个位置,故状态压缩 枚举每个状态即可,同时应该 注意的是 每行的状态是由上面一行和上面两行 的状态决定的。
另外,可以知道一个位置有炮兵,则左右两个空位置不能有炮兵,因此可以先把 有效状态提取出来,然后在判断这个状态的时候,再判断这个位置是否是山地。
代码如下:
题目大意:
在N*M的网格地图上部署炮兵部队。地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图。在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队);一支炮兵部队在地图上的攻击范围如图中黑色区域所示:
![](http://poj.org/images/1185_1.jpg)
如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域。炮兵的攻击范围不受地形的影响。
现在,如何部署炮兵部队,使得任何一支炮兵部队都不在其他支炮兵部队的攻击范围内,在整个地图区域内最多能够摆放多少我军的炮兵部队。
解题思路:由于每行最多只有10个位置,故状态压缩 枚举每个状态即可,同时应该 注意的是 每行的状态是由上面一行和上面两行 的状态决定的。
另外,可以知道一个位置有炮兵,则左右两个空位置不能有炮兵,因此可以先把 有效状态提取出来,然后在判断这个状态的时候,再判断这个位置是否是山地。
代码如下:
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; int dp[105][70][70]; ///dp[i][j][k]:第i行为状态j,i-1行为状态k的最大放法 int sta[70]; ///合法状态数 int cot[70]; ///合法状态下本行能放的炮兵数 int map[1<<11]; ///存地图 int n,m; int init() { memset(dp,0,sizeof(dp)); memset(sta,0,sizeof(sta)); memset(map,0,sizeof(map)); memset(cot,0,sizeof(cot)); } void solve() { int num=(1<<m); int ct=0; for(int i=0;i<=num;i++) ///枚举合法状态 if( (i&(i<<1))==0 && (i&(i<<2))==0 )///注意(i&(i<<1))==0不能写成(i&(i<<1)==0),(==优先级高于&) sta[ct++]=i; for(int i=0;i<ct;i++) ///计算合法状态炮兵数 { int cn=0; for(int j=0;j<=m;j++) if( sta[i]&(1<<j) ) cn++; cot[i]=cn; if( (map[1]|sta[i])==map[1] ) dp[1][i][0]=cn; ///初始化第一行,零行为0 } for(int i=2; i<=n; i++) { //if(map[i]==0) continue; for(int k1=0; k1<ct; k1++) { if((sta[k1]|map[i-1])!=map[i-1]) continue; for(int k2=0; k2<ct; k2++) { if( (sta[k2]|map[i-2])!=map[i-2] ) continue; if( (sta[k1]&sta[k2])!=0 ) continue; for(int j=0; j<ct; j++) if( (sta[j]|map[i])==map[i] && (sta[j]&sta[k1])==0 && (sta[j]&sta[k2])==0 ) dp[i][j][k1]=max(dp[i][j][k1],dp[i-1][k1][k2]+cot[j]); } } } int ans=0; for(int i=0;i<ct;i++) for(int j=0;j<ct;j++) ans=max(dp [i][j],ans); printf("%d\n",ans); } int main() { //freopen("in.txt","r",stdin); int t; scanf("%d",&t); while(t--) { init(); scanf("%d%d",&n,&m); if(m==0||n==0) {printf("0\n");continue;} char s[12]; for(int i=1;i<=n;i++) { scanf("%s",s); for(int j=0;j<m;j++) if(s[j]=='P') map[i]=(map[i]<<1)+1;///从左往右1为P(平原),0为H(山地) else map[i]=(map[i]<<1)+0; } solve(); } return 0; }
相关文章推荐
- POJ 1185 炮兵阵地(动态规划+状态压缩)
- POJ 1185 炮兵阵地 (状态压缩dp)
- Noi 01炮兵阵地 & poj1185 &NYOJ81 炮兵阵地 状态压缩和动态规划
- poj 1185 炮兵阵地 (状态压缩 dp)
- POJ 1185 炮兵阵地(状态压缩DP)
- POJ - 1185 炮兵阵地 状态压缩DP
- poj 1185 炮兵阵地 [经典状态压缩DP]
- POJ 1185 炮兵阵地(状态压缩dp)
- poj 1185 炮兵阵地 状态压缩dp
- poj 1185 炮兵阵地 (状态压缩)
- POJ 1185 炮兵阵地 (状态压缩DP)
- POJ 1185 炮兵阵地 状态压缩(DP)
- POJ 1185 炮兵阵地 状态压缩dp
- POJ 1185 炮兵阵地(状态压缩DP)
- poj 1185 炮兵阵地(状态压缩DP)
- 炮兵阵地 POJ - 1185(状态压缩)
- POJ 炮兵阵地 1185 状态压缩dp
- POJ 1185 炮兵阵地 (状态压缩DP)
- poj 1185 炮兵阵地 状态压缩dp
- poj 1185 炮兵阵地 (压缩状态DP)