poj1185(状压dp)
题目连接:http://poj.org/problem?id=1185
题意:给出一张n*m的地图,'H'表示高地,不能部署炮兵,'P'表示平原,可以部署炮兵,炮兵之间必须保持横向、纵向至少2个格子的距离,保证没有误伤。问最多可以部署多少炮兵。
分析:对于每行大炮的状态仅与上两行的状态有关,因此要开个三维的数组来表示状态,当前行的状态可由前两行的状态转移而来。
当前行的最大值就是上一个状态的值加上当前状态中1的个数(当前行放大炮的个数)。
dp[i][j][k]表示到第i行时第i行的状态为j,第i-1行的状态为k的最大值,则dp[i][j][k] =max(dp[i][j][k],dp[i-1][k][l]+num[j]); num[j]为i状态中1的个数。
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <stack>
#include <vector>
#include <set>
#include <map>
#define LL long long
#define mod 100000000
#define inf 0x3f3f3f3f
#define eps 1e-9
#define N 100010
#define FILL(a,b) (memset(a,b,sizeof(a)))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
int dp[][][],n,m,tot;
int cur[],state[],num[];
char s[][];
bool ok(int x)
{
if(x&(x<<))return ;
if(x&(x<<))return ;
return ;
}
bool fit(int state,int k)//判断状态state在第k行是否符合
{
if(state&cur[k])return ;
return ;
}
void init()//预处理每行符合条件的所有状态
{
int sum=<<m;
tot=;
for(int i=;i<sum;i++)
{
if(ok(i))state[++tot]=i;
}
}
int cal(int x)//计算该状态二进制的1的个数
{
int res=;
while(x)
{
if(x&)res++;
x>>=;
}
return res;
}
int main()
{
while(scanf("%d%d",&n,&m)>)
{
if(m+n==)break;
init();
for(int i=;i<=n;i++)scanf("%s",s[i]+);
for(int i=;i<=n;i++)
{
cur[i]=;
for(int j=;j<=m;j++)
{
if(s[i][j]=='H')cur[i]+=<<(m-j);
}
}
FILL(dp,);
for(int i=;i<=tot;i++)
{
num[i]=cal(state[i]);
if(fit(state[i],))dp[][i][]=num[i];
}
for(int i=;i<=n;i++)
{
for(int j=;j<=tot;j++)
{
if(!fit(state[j],i))continue;
for(int k=;k<=tot;k++)
{
if(!fit(state[k],i-))continue;
if(state[j]&state[k])continue;
for(int l=;l<=tot;l++)
{
if(state[l]&state[k])continue;
if(state[l]&state[j])continue;
if(i>&&!fit(state[l],i-))continue;
dp[i][j][k]=max(dp[i][j][k],dp[i-][k][l]+num[j]);
}
}
}
}
int ans=;
for(int i=;i<=n;i++)
for(int j=;j<=tot;j++)
for(int k=;k<=tot;k++)
ans=max(ans,dp[i][j][k]);
printf("%d\n",ans);
}
}
poj1185(状压dp)的更多相关文章
- POJ1185 状压dp(二进制//三进制)解法
很显然这是一道状压dp的题目 由于每个最优子结构和前两行有关,一个显而易见的想法是用三维dp[i][j][k]用来记录在第i行下为j状态,i - 1行为k状态时的最大值,然而dp[100][1 < ...
- [poj1185]炮兵阵地_状压dp
炮兵阵地 poj-1185 题目大意:给出n列m行,在其中添加炮兵,问最多能加的炮兵数. 注释:n<=100,m<=10.然后只能在平原的地方建立炮兵. 想法:第2到状压dp,++.这题显 ...
- 【POJ1185】炮兵阵地(状压DP)
题意: 思路:状压DP经典题 可以预处理下每一行内合法的状态,发现很少 所以转移时可以使用状态的编号而不是状态本身 DP时记录前两行状态的编号进行转移和判断 #include<cstdio> ...
- poj1185:炮兵阵地(状压dp)
也算是比较基础的状压dp了,跟做过的第二道比较又稍微复杂了一点 需要记录之前两行的状态.. 统计结果也稍有不同 另外还学习了一个得到一个整数二进制位 1 的个数的位运算方法 详见代码: #includ ...
- 2018.09.08 poj1185 炮兵阵地(状压dp)
传送门 状压dp经典题. 我们把每一行的状态压成01串. 预处理出每一行可能出现的状态,然后转移每个被压缩的状态的1的个数就行了. 注意当前行转移要考虑前两行的状态. 还要注意只有一行的情况. 代码: ...
- POJ1185 炮兵阵地 —— 状压DP
题目链接:http://poj.org/problem?id=1185 炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions ...
- HDU 1565 - 方格取数(1) - [状压DP][网络流 - 最大点权独立集和最小点权覆盖集]
题目链接:https://cn.vjudge.net/problem/HDU-1565 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32 ...
- 算法复习——状压dp
状压dp的核心在于,当我们不能通过表现单一的对象的状态来达到dp的最优子结构和无后效性原则时,我们可能保存多个元素的有关信息··这时候利用2进制的01来表示每个元素相关状态并将其压缩成2进制数就可以达 ...
- BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3336 Solved: 1936[Submit][ ...
- nefu1109 游戏争霸赛(状压dp)
题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...
随机推荐
- 非确定有限状态自动机的构建(一)——NFA的定义和实现
保留版权,转载需注明出处(http://blog.csdn.net/panjunbiao). 非确定有限状态自动机(Nondeterministic Finite Automata,NFA)由以下元素 ...
- delphiXE调用Objective-c库
http://stackoverflow.com/questions/16515218/xe4-firemonkey-ios-static-library-pascal-conversion-from ...
- perl 匿名函数传参
$subref=sub { my $a=shift; return $a; }; print $subref->("xxyyzz");
- JavaScript编程:javaScript核心基础语法
1.javaScript核心基础语法: javaScript技术体系包含了5个内容: 1.核心语言定义: 2.原生对象和雷子对象: 3.浏览器对象 ...
- Android中View绘制优化之一---- 优化布局层次
本文原创, 转载请注明出处:http://blog.csdn.net/qinjuning 前言,竟然是翻译,当然得弄的有板有眼. 照着大作家格式来咯 , - - . 译序 最近一直在做锁屏界面,之前也 ...
- 用js制作的几个效果
一,表格光柱效果(奇偶行不同颜色,鼠标移上变色) <html xmlns="http://www.w3.org/1999/xhtml"><head>< ...
- JSP的学习(3)——语法知识二之page指令
本篇接上一篇<JSP的学习(2)——语法知识一>,继续来学习JSP的语法.本文主要从JSP指令中的page指令,对其各个属性进行详细的学习: JSP指令: JSP指令是为JSP引擎而设计的 ...
- QNX系统-关于delay函数与sleep函数的区别
QNX是类unix系统.在c语言编程过程中,往往会用到delay或者sleep延时函数.两者之间在使用上有一定的区别!!! delay()是循环等待,该进程还在运行,占用处理器. sleep()不同, ...
- 2014 Multi-University Training Contest 1 — D. Task
题目链接:pid=4864">http://acm.hdu.edu.cn/showproblem.php?pid=4864 题目大意: 有N个机器.M个任务. 当中每一个机器有xi,y ...
- HDU 4344 随机法判素数(费马小定理
#include <cstdio> #include <ctime> #include <cmath> #include <algorithm> usi ...