炮兵阵地 POJ

来源:互联网 发布:oracle数据库log文件 编辑:程序博客网 时间:2024/06/01 12:49

炮兵阵地
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 27960 Accepted: 10821

Description

司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队。一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图。在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队);一支炮兵部队在地图上的攻击范围如图中黑色区域所示:

如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格。图上其它白色网格均攻击不到。从图上可见炮兵的攻击范围不受地形的影响。
现在,将军们规划如何部署炮兵部队,在防止误伤的前提下(保证任何两支炮兵部队之间不能互相攻击,即任何一支炮兵部队都不在其他支炮兵部队的攻击范围内),在整个地图区域内最多能够摆放多少我军的炮兵部队。

Input

第一行包含两个由空格分割开的正整数,分别表示N和M;
接下来的N行,每一行含有连续的M个字符('P'或者'H'),中间没有空格。按顺序表示地图中每一行的数据。N <= 100;M <= 10。

Output

仅一行,包含一个整数K,表示最多能摆放的炮兵部队的数量。

Sample Input

5 4PHPPPPHHPPPPPHPPPHHP

Sample Output

6

Source


题目链接:http://poj.org/problem?id=1185
 
题目:在一个N*M的矩阵上布置炮兵部队,P为平原,H为山地,只有平原可以布置炮兵部队,
    然后每个炮兵部队都有一个攻击范围,它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格。

问:如何部署炮兵部队,在防止误伤的前提下
   (保证任何两支炮兵部队之间不能互相攻击,即任何一支炮兵部队都不在其他支炮兵部队的攻击范围内),
    在整个地图区域内最多能够摆放多少我军的炮兵部队?

 Corn Fields POJ - 3254 的升级版
 
预处理合法状态state[],并计算每个合法状态中1的个数num[]
dp[i][s1][s2] 表示当前行状态为s1,上一行状态为s2的最多炮兵数
dp[i][s1][s2] = max{ dp[i][s1][s2],  num[s] + dp[i - 1][s2][s3] }
        其中当前行状态为s1, 上一行状态为s2,上上行状态为s3,且 s1,s2,s3互相兼容 且都与地图兼容

这里我滚动了数组,因此
     dp[z][s1][s2] = max{ dp[z][s1][s2],  num[s] + dp[1 - z][s2][s3] }
        (z = i % 2)


#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <queue>#include <string>#define LL long long#define inf 0x3f3f3f3f#define INF 1e18using namespace std;typedef pair<int, int> P;const int maxn = 2e5 + 5;const int mod = 1e8;int dp[2][65][65];int state[65], cnt, num[65];int mp[105];int n, m; int main(void){//std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);//freopen("in.txt", "r", stdin); char ch;while (~scanf("%d %d", &n, &m)){cnt = 0;memset(state, 0, sizeof state);memset(num, 0, sizeof num); for (int s = 0; s < (1 << m); s++){if (s & (s << 1)) continue;if (s & (s << 2)) continue;state[++cnt] = s;for (int i = 0; i < m; i++)if (s & (1 << i)) num[cnt]++; } memset(dp, 0, sizeof dp);memset(mp, 0, sizeof mp);for (int i = 1; i <= n; i++){getchar();for (int j = 1; j <= m; j++){scanf("%c", &ch);if (ch == 'H') mp[i] += (1 << (j-1)); // H位置赋值1,P位置赋值0,方便位运算 } }for (int s = 1; s <= cnt; s++){  // 第1行 if (!(mp[1] & state[s])) dp[1][s][1] = num[s];}// 滚动数组,注意当 n==1 for (int s = 1; s <= cnt; s++){  // 第2行 if (mp[2] & state[s]) continue;for (int k = 1; k <= cnt; k++){if (mp[1] & state[k]) continue;if (state[s] & state[k]) continue;dp[0][s][k] = max(dp[0][s][k], num[s] + dp[1][k][1]);}}int z = 0;for (int i = 3; i <= n; i++){z = i % 2;memset(dp[z], 0, sizeof dp[z]);for (int s1 = 1; s1 <= cnt; s1++){if (mp[i] & state[s1]) continue; // 状态s1与地图兼容 for (int s2 = 1; s2 <= cnt; s2++){if (mp[i - 1] & state[s2]) continue; // 状态s2与地图兼容 if (state[s1] & state[s2]) continue; // 状态s1与s2兼容 for (int s3 = 1; s3 <= cnt; s3++){if (mp[i - 2] & state[s3]) continue; // 状态s3与地图兼容 if (state[s1] & state[s3]) continue; // 状态s1与s3兼容 if (state[s2] & state[s3]) continue; // 状态s2与s3兼容 dp[z][s1][s2] = max(dp[z][s1][s2], num[s1] + dp[1 - z][s2][s3]);}}}}int ans = -1;for (int s = 1; s <= cnt; s++)for (int k = 1; k <= cnt; k++)ans = max(ans, dp[n % 2][s][k]);//ans = max(ans, dp[z][s][k]);  当 n==1,这样就写wa了,看了半天。。。cout << ans << endl;}return 0;}/*5 4PHPPPPHHPPPPPHPPPHHP6 */




原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 战地1下载不了怎么办 手机解压包异常怎么办 电脑显示文件损坏怎么办 360解压坏了怎么办 dnf邮箱满了怎么办 origin会员过期存档怎么办 电脑文件夹删除不了怎么办 黑苹果内核错误怎么办 win10文件夹拒绝访问怎么办 苹果电脑没有系统了怎么办 黑苹果安装之后怎么办 笔记本cpu核显坏了怎么办 粘贴大量文件卡住怎么办 mx不能播放rv40怎么办 迷你世界联机卡怎么办 绝地求生被火瓶烧了怎么办 win8电脑太卡怎么办 win8关机没反应怎么办 arma3没子弹了怎么办 g350d柴油冻了怎么办 散热硅胶干了怎么办 电脑打不开pdf文件怎么办 文件变成快捷方式打不开怎么办 ai文件打不开了怎么办 电脑下载了病毒软件怎么办 打嗝停不下来怎么办 咳嗽停不下来怎么办 电动机停不下来怎么办 电脑所有程序都打不开怎么办 机顶盒画面卡顿怎么办 电脑画面卡顿怎么办 鞋舌头跑偏怎么办 球球大作战老卡怎么办 孩子被打却不敢还手怎么办? 自卫砍伤了人怎么办 系统还原节点黑屏了怎么办 我惹事了要被打怎么办 诛仙宠物太多怎么办 笔记本玩lolfps低怎么办 lol延迟有42怎么办 软件安装后黑屏怎么办