思路:定义一个三维数组dp[x][i][j]其中x为now和pre两种状态,now表示当前两行最优解,pre表示出了本行外,前两行的最优解。那么状态转移方程为

dp[now][j][k]=max(dp[now][j][k],dp[pre][k][r]+num[i][j][1])。num[i][j][1]表示第i行的第j个状态的1的个数。转移条件是!(num[i][j][0]&num[i-1][k][0])&&!(num[i][j][0]&num[i-2][r][0])&&!(num[i-1][k][0]&num[i-2][r][0])为真。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#define Maxn 1010
using namespace std;
int dp[][Maxn][Maxn],now,pre,num[][Maxn][],cnt1,cnt2,cnt3,graphic[][],n,m;
void dfs(int u,int j,int f)
{
int i;
if(j==m)
{
int sum,cc;
sum=cc=;
for(i=m;i>=;i--)
{
sum+=graphic[u][i]*(<<(m-i));
if(graphic[u][i])
cc++;
}
if(f<=)
{
if(graphic[u][j])
{
if(sum!=)
{
num[u][++cnt1][]=sum-;
num[u][cnt1][]=cc-;
}
}
else
{
num[u][++cnt1][]=sum;
num[u][cnt1][]=cc;
}
}
else
{
if(graphic[u][j])
{
if(sum!=)
{
num[u][++cnt1][]=sum-;
num[u][cnt1][]=cc-;
}
num[u][++cnt1][]=sum;
num[u][cnt1][]=cc;
}
else
{
num[u][++cnt1][]=sum;
num[u][cnt1][]=cc;
}
}
return ;
}
if(f<=)
{
if(graphic[u][j]==)
{
graphic[u][j]=;
dfs(u,j+,f+);
graphic[u][j]=;
}
else
dfs(u,j+,f+);
}
else
{
if(graphic[u][j])
{
dfs(u,j+,);
graphic[u][j]=;
dfs(u,j+,f+);
graphic[u][j]=;
}
else
dfs(u,j+,f+);
}
}
void out(int x)
{
if(x==||x==)
{
printf("%d",x);
return ;
}
int temp=x%;
out(x/);
printf("%d",temp);
}
int main()
{
int i,j,k,r;
char str[];
memset(graphic,,sizeof(graphic));
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(dp,,sizeof(dp));
memset(num,,sizeof(num));
memset(graphic,,sizeof(graphic));
for(i=;i<=n;i++)
{
scanf("%s",&str);
for(j=;j<m;j++)
{
if(str[j]=='P')
graphic[i][j+]=;
else
graphic[i][j+]=;
}
}
dfs(,,);
cnt2=cnt1;
cnt1=;
dfs(,,);
now=,pre=;
for(i=;i<=cnt2;i++)
for(j=;j<=cnt1;j++)
{
if(!(num[][i][]&num[][j][]))
dp[now][j][i]=num[][i][]+num[][j][];
}
for(i=;i<=n;i++)
{
cnt3=cnt2,cnt2=cnt1,cnt1=;
dfs(i,,);
now=!now,pre=!pre;
for(j=;j<=cnt1;j++)
for(k=;k<=cnt2;k++)
for(r=;r<=cnt3;r++)
{
if(!(num[i][j][]&num[i-][k][])&&!(num[i][j][]&num[i-][r][])&&!(num[i-][k][]&num[i-][r][]))
dp[now][j][k]=max(dp[now][j][k],dp[pre][k][r]+num[i][j][]);
}
}
int ans=;
for(i=;i<=cnt1;i++)
for(j=;j<=cnt2;j++)
{
ans=max(ans,dp[now][i][j]);
}
printf("%d\n",ans);
}
return ;
}

poj 1185 炮兵阵地 状态压缩dp的更多相关文章

  1. POJ - 1185 炮兵阵地 (状态压缩)

    题目大意:中文题目就不多说大意了 解题思路: 1.每行最多仅仅有十个位置,且不是山地就是平原,那么就能够用1表示山地,0表示平原,将每一行的状态进行压缩了 2.接着找出每行能放炮兵的状态.先不考虑其它 ...

  2. POJ 3254 炮兵阵地(状态压缩DP)

    题意:由方格组成的矩阵,每个方格可以放大炮用P表示,不可以放大炮用H表示,求放最多的大炮,大炮与大炮间不会互相攻击.大炮的攻击范围为两个方格. 分析:这次当前行的状态不仅和上一行有关,还和上上行有关, ...

  3. POJ 1185 炮兵阵地 状压dp

    题目链接: http://poj.org/problem?id=1185 炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K 问题描述 司令部的将军们打算在N*M ...

  4. POJ1185 - 炮兵阵地(状态压缩DP)

    题目大意 中文的..直接搬过来... 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平 ...

  5. poj - 1185 炮兵阵地 状压DP 解题报告

    炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 21553   Accepted: 8363 Description ...

  6. POJ 1185炮兵阵地 (状压DP)

    题目链接 POJ 1185 今天艾教留了一大堆线段树,表示做不动了,就补补前面的题.QAQ 这个题,我第一次写还是像前面HDU 2167那样写,发现这次影响第 i 行的还用i-2行那样,那以前的方法就 ...

  7. [poj 1185] 炮兵阵地 状压dp 位运算

    Description 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用&quo ...

  8. luogu2704 炮兵阵地 状态压缩DP

    题目大意:一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),在每一格平原地形上最多可以布置一支炮兵部队,能攻击到的区域:沿横向左右各两格,沿纵向上 ...

  9. POJ1185炮兵阵地(状态压缩 + dp)

    题目链接 题意:给出一张n * m的地图,其中 有的地方能放大炮,有的地方不能,大炮与上下左右两个单位范围内会相互攻击,问最多能放几个大炮 能放大炮为1不能放大炮为0,把每一行看做一个状态,要除去同一 ...

随机推荐

  1. Cygwin的包管理器:apt-cyg

    参考<Cygwin的包管理器:apt-cyg> cygwin下安装每次需要启动set_up,比较蛋疼,还是debian的apt方便,在网上看到应该cygwin 下的apt,觉得不错. 从h ...

  2. #elif

    http://baike.sogou.com/v72031124.htm?fromTitle=%23elif #else指令用于某个#if指令之后,当前面的#if指令的条件不为真时,就编译#else后 ...

  3. JMS开发(二):深入PTP,Pub-Sub两种模式

    1.PTP模型 PTP(Point-to-Point)模型是基于队列(Queue)的,对于PTP消息模型而言,它的消息目的是一个消息队列(Queue),消息生产者每次发送消息总是把消息送入消息队列中, ...

  4. 关于在Eclipse中使用正则表达式替换的一点记录(使用正则表达式的分组)

    今天在工作中遇到了点替换的麻烦事,由于数据类进行了变动,具体情况是这样的,需要将下面的代码: player.skillData[i].name 替换为: player.skillData.getSki ...

  5. MVC神韵---你想在哪解脱!(十二)

    追加一条电影信息 运行应用程序,在浏览器中输入“http://localhost:xx/Movies/Create”,在表单中输入一条电影信息,然后点击追加按钮,如图所示. 点击追加按钮进行提交,表单 ...

  6. EcTouch二次开发

    一.EcTouch简介 1.1. 什么是ECTOUCH ECTouch是上海商创网络科技有限公司推出的一款开源免费移动商城网店系统,可以在手机上面卖商品的电子商务软件系统.能够帮助企业和个人快速构建手 ...

  7. php and web service with wsdl

    Following are the links: Developing Web Services Using PHP PHP Web Services with WSDL Creating Web S ...

  8. PostgreSQL的 initdb 源代码分析之二十一

    继续分析: setup_schema(); 展开: 实质就是创建info_schema. cmd 是: "/home/pgsql/project/bin/postgres" --s ...

  9. 解决statusStrip控件上的项目不能靠右对齐的问题

    在c#中用到了状态栏控件StatusStrip,但当我想把StatusStrip上某个StatusLabel靠右对齐时出了问题. 按照MSDN中的办法,是设置ToolStripStatusLabel的 ...

  10. 使用C#: 自动切换鼠标的左右手习惯

    不知道我得的是鼠标手,还是肩周炎. 长时间右手(或者左手)使用鼠标的话,那只胳膊便会不自在. 于是便有了切换鼠标主次要键的需求. [控制面板->鼠标]有更改它的设置,可点来点去让我觉得不够方便. ...