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 ...
随机推荐
- Post model至Web Api
Post model可以解决多动态性的参数至Web Api中去,获取数据或是创建数据.如果一个对象有很多字段,需要对每一个字段进行查询或是在创建对象时,我们可以考虑使用model来作参数.这样不必在控 ...
- Div和Span标签显示与隐藏
本实例中,学习jQuery的知识,显示与隐藏网页上的div或是span标签. 实际环境中,也许是根据某些条件进行,符合条件时,对某个或是某个div或是span标签时行显示与隐藏. 主要是学习jQuer ...
- 折腾了1周把程序从sqlserver迁移到oracle上了,每折腾一次需要耗费1周时间
主要花费时间的事情: 1:安装配套的服务器,安装操作系统,安装数据库,配置远程访问等等,一般会耗费1天时间,甚至2天时间,若手头安装盘不齐全,需要耗费更多时间. 2:远程传输安装文件.特别是开发环境等 ...
- window.history 和 DWZ 框架
DWZ框架的ajax请求返回的一般都是一个HTML片段,整个页面是由一个个HTML片段组成的,可以由TAB切换其内容,但是只有一个body和HEAD,一般head 和 菜单栏是不会动的. 今天遇到一个 ...
- java 客户端链接不上redis解决方案
原文地址:http://blog.csdn.net/yingxiake/article/details/51472810 出现问题描述: 1.Could not get a resource from ...
- 防止 JavaScript 自动插入分号
JavaScript语言有一个机制:在解析时,能够在一句话后面自动插入一个分号,用来修改语句末尾遗漏的分号分隔符. 然而,由于这个自动插入的分号与JavaScript语言的另一个机制发生了冲突,即所有 ...
- 微信公众平台开发(71)OAuth2.0网页授权
微信公众平台开发 OAuth2.0网页授权认证 网页授权获取用户基本信息 作者:方倍工作室 微信公众平台最近新推出微信认证,认证后可以获得高级接口权限,其中一个是OAuth2.0网页授权,很多朋友在使 ...
- Android闹钟设置的解决方案
Android设置闹钟并不像IOS那样这么简单,做过Android设置闹钟的开发者都知道里面的坑有多深.下面记录一下,我解决Android闹钟设置的解决方案. 主要问题 API19开始AlarmMan ...
- react的基本学习
1.<SubSubComp {...this.props } /> 传递属性,{...props}的方式为组件传递了这两个属性,这就是JSX中的延展属性,"..."成为 ...
- 【技术】JavaSE环境下JPA实体类自动注册
在没有容器支持的环境下,JPA的实体类(Entity)一般要在persistence.xml中逐个注册,类似下面这样: <?xml version="1.0" encodin ...