POJ1185 炮兵阵地
司令部的将军们打算在N × M的网格地图上部署他们的炮兵部队。一个N × M的地图由N行M列组成,地图的每一格可能是山地(用"H"表示),也可能是平原(用"P"表示),如下图。在每一格平原地形上最多可以布置一支炮兵部队 (山地上不能够部署炮兵部队);一支炮兵部队在地图上的攻击范围如图中黑色区域所示:
如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格。图
上其它白色网格均攻击不到。从图上可见炮兵的攻击范围不受地形的影响。
现在,将军们规划如何部署炮兵部队,在防止误伤的前提下(保证任何两支炮兵部队之间不能互相攻击,即任何一支炮兵部队都不在其他支炮兵部队的攻击范围
内),在整个地图区域内最多能够摆放多少我军的炮兵部队。
输入描述
Input Description
第一行包含两个由空格分割开的正整数,分别表示N和M;
接下来的N行,每一行含有连续的M个字符('P'或者'H'),中间没有空格。按顺序表示地图中每一行的数据。N ≤ 100, M ≤ 10。
输出描述
Output Description
仅一行,包含一个整数K,表示最多能摆放的炮兵部队的数量。
样例输入
Sample Input
5 4
PHPP
PPHH
PPPP
PHPP
PHHP
样例输出
Sample Output
6
正解:状压DP
解题报告:
今天考试T4。
这是一道状压DP裸题,我一上来就看到这道题,就知道是NOI2001原题,然而我并没有想到怎么做。因为我一直很纠结这一行的决策会受上两行的影响,所以总在想着用一个什么三进制数来表示,然而总是没想通。其实并不需要三进制,就用常规的二进制思路就可以做这道题了。我用一个二进制数S,1表示放炮兵,0表示不放,显然对于每一行可以预处理一下哪些状态是可行的。位运算可以大大加速预处理速度。并且我们可以发现,一行的可行的状态数很少,而且绝对不会超过60。那么这就很好做了,我预处理出每一行的可行状态,存下来,并且算一下当前状态下的炮兵数量,每次枚举的时候我只考虑这些可行状态,就可以大大加速,避免了许多无用状态的讨论。然后,因为当前行的决策要受上两行的影响,既然要受影响,那么我不妨把状态记下来。我用f[i][S1][S2]表示第i行放状态为S1,i-1行放S2的最大值。这样的话转移也很明了了,我枚举一个i-2行的状态K1,所以f[i][S1][S2]=max(f[i-1][S2][K1]+cnt[S1],f[i][S1][S2]),也就是说我每次需要枚举三个状态。显然,第一行我们需要特殊处理,直接把第一行的所有情况算出来,为了方便处理边界,我可以给第0行增加一种状态0,这样方便转移。其余的就是一些细节了,比如果S1、S2、K1互不冲突的判断,位运算可以随便过啦。
//It is made by jump~
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
const int inf = (<<);
const int MAXN = ;
const int MAXM = ;
int n,m,ans,end;
int a[MAXN][];
char ch[];
int f[MAXN][][];//f[i][S1][S2]表示第i行放状态为S1,i-1行放S2的最大值
int dix[MAXN];
int mp[MAXN][],cnt[MAXN][],num[MAXN];//每一行可行状态最多60种 inline int getint()
{
int w=,q=; char c=getchar();
while((c<'' || c>'') && c!='-') c=getchar(); if(c=='-') q=,c=getchar();
while (c>='' && c<='') w=w*+c-'', c=getchar(); return q ? -w : w;
} inline int get_cnt(int s){ int total=; while(s) total+=s&,s>>=; return total; } inline void work(){
n=getint(); m=getint();
for(int i=;i<=n;i++) {
scanf("%s",ch);
for(int j=;j<m;j++) {
if(ch[j]=='P') a[i][j+]=;
else a[i][j+]=;
dix[i]|=a[i][j+]*(<<j);
}
}
end=(<<m)-;
for(int i=;i<=n;i++) {
for(int s=;s<=end;s++) {
if(( s&(s<<) )!=) continue; if(( s&(s<<) )!=) continue;
if((dix[i]&s)!=s) continue;
num[i]++; mp[i][num[i]]=s; cnt[i][num[i]]=get_cnt(s);
}
}
num[]++; for(int i=;i<=n;i++) for(int j=;j<=num[];j++) f[][j][]=cnt[][j];
int now,k1,k2;
for(int i=;i<=n;i++) {
for(int j=;j<=num[i-];j++) {
k1=mp[i-][j];
for(int k=;k<=num[i-];k++) {
k2=mp[i-][k]; if(f[i-][j][k]==) continue;
for(int l=;l<=num[i];l++) {
now=mp[i][l]; if((now&k1)!=) continue; if((now&k2)!=) continue;
f[i][l][j]=max(f[i][l][j],f[i-][j][k]+cnt[i][l]);
}
}
}
}
for(int i=;i<=num[n];i++) for(int j=;j<=num[n-];j++) ans=max(ans,f[n][i][j]);
printf("%d",ans);
} int main()
{
work();
return ;
}
POJ1185 炮兵阵地的更多相关文章
- [poj1185]炮兵阵地_状压dp
炮兵阵地 poj-1185 题目大意:给出n列m行,在其中添加炮兵,问最多能加的炮兵数. 注释:n<=100,m<=10.然后只能在平原的地方建立炮兵. 想法:第2到状压dp,++.这题显 ...
- POJ1185炮兵阵地【动态规划】
炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 26892 Accepted: 10396 Descriptio ...
- poj1185 炮兵阵地【状压DP】
炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 32802 Accepted: 12650 Descriptio ...
- POJ1185 炮兵阵地 —— 状压DP
题目链接:http://poj.org/problem?id=1185 炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions ...
- POJ1185 炮兵阵地 和 POJ2411 Mondriaan's Dream
炮兵阵地 Language:Default 炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 34008 Accepted ...
- poj1185炮兵阵地
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> ...
- POJ1185 - 炮兵阵地(状态压缩DP)
题目大意 中文的..直接搬过来... 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平 ...
- POJ1185 炮兵阵地 状态压缩
因为不知道不同的博客怎么转,就把别人的复制过来了,这个题解写的非常好,原地址为: http://hi.baidu.com/wangxustf/item/9138f80ce2292b8903ce1bc7 ...
- poj1185炮兵阵地 正确代码及错误代码分析
Solution:状态压缩 因为设置炮兵的局限性(同行两炮兵相差要大于2),一行10个数最多有60种可能性(程序计算) 其中判断可能性的好方法是: if ((i & (i << 1 ...
随机推荐
- VFS分析(二)基本数据结构(持续更新)
nameidata /mnt/dir1/dir2/ nameidata结构体是一个临时的结构体, 目标是为了找到最后的dentry.
- OmniPlan文档链接
https://support.omnigroup.com/documentation/omniplan/mac/3.0/zh/introduction/#introduction
- Jenkins持续集成
Jenkins持续集成 & .NET 最近受累于测试环境每次发布都很麻烦,而且我们有多个测试环境,因此专门抽时间做了Jenkins的配置和研究. 折腾了两天终于绿灯以后,先来个截图,Blu ...
- 关于div标签的title属性一闪一闪不正常显示的原因
弹出了chrome的开发工具就会出现以上问题.
- mysql 控制台上传数据库
运行 0.cmd1.cd/d d:\DedeAMPZ\Program\MySQL\bin2.mysql -uroot -p1234563.use 数据库名4.source XX.sql 文件所在路 ...
- ReactNative运行提示缺少文件xxxRootView.h解决方法
我们经常在github获取源码后运行会出现缺少 "RCTRootView.h" notfound" 文件的错误,对于这种错误我们怎么解决了. 1.cd到项目根目录 删除项 ...
- hdu5444Elven Postman(主席树思想的应用)
主席树这个概念应该不陌生吧!恩?不会, 戳这里. 主席树(函数式线段树)用的是函数思想,一个节点开数组用来保存自己的左右节点,这样节省许多不必要的空间,还可以保存许多历史状态.而这里我们用的是主席树的 ...
- 爱春秋之戏说春秋 Writeup
爱春秋之戏说春秋 Writeup 第一关 图穷匕见 这一关关键是给了一个图片,将图片下载到本地后,打开以及查看属性均无任何发现,尝试把图片转换为.txt格式.在文本的最后发现这样一串有规律的代码: 形 ...
- 反射 实现不同模型相同属性赋值 第二集(automapper)
前言: 两年前写过一个 反射实现不同模型相同属性赋值 只能简单的实现两个model 相同属性名,相同类型赋值 最近又遇到这个问题,需要对相同属性名或者指定属性名 不同类型(复杂对象,如:List< ...
- Linux epoll 笔记(高并发事件处理机制)
wiki: Epoll优点: Epoll工作流程: Epoll实现机制: epollevent; Epoll源码分析: Epoll接口: epoll_create; epoll_ctl; epoll_ ...