题目:http://poj.org/problem?id=1185

大神的题解:

方法就是用DP[i][r][p]表示第i行状态为r,第i-1行状态是p时的最多个数。而这里p受到r的限制,而第i-2行状态q则受到r和p两个状态限制。状态转移方程就是:

DP[i][r][p] = MAX{DP[i-1][p][q] +num[r]}

其中,p是受到r的限制时枚举的状态,q是受到r和p共同限制时候的状态,num[r]表示状态r里面的布局炮兵所摆的个数。

这里我们可以看到就要枚举i,r,p,q,这4 个变量,i的范围是100,而其他几个则都是1<<10,复杂度颇为偏高。而实际上由于每一行里面有很多都是某些位置被其他位置影响的。比如:   1110001,  如果第一个位置放上炮兵,那么第二第三的位置都会受到影响,而一个也放不了。

解决方案就是不去管那些相互有影响的状态,把形如:

1000000    0100000    ... ...

1001000    0100001    ... ...

...

1001001

这些相互之间没有影响的状态找出来,这样所有的状态数就会减少至少于60种(我算了一下,好像是58种),这样一来就是60*60*60*100,可以过了。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#define mod 100000000
using namespace std;
int m,n,top,state[],cur[],num[],dp[][][];
char tu[][];
inline bool ok(int x)
{
if(x&(x<<)) return false;
if(x&(x<<)) return false;
return true;
}
inline void init()
{
int tol=<<n;
top=;
for(int i=; i<tol; i++)
{
if(ok(i)) state[++top]=i;
}
}
inline bool fit(int x,int k)
{
if(x&cur[k]) return false;
return true;
}
inline int icount(int x)
{
int cnt=;
while(x)
{
cnt++;
x=x&(x-);
}
return cnt;
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
init();
for(int i=; i<=m; i++)
scanf("%s",tu[i]+);
for(int i=;i<=m;i++)
{
cur[i]=;
for(int j=;j<=n;j++)
{
if(tu[i][j]=='H')
cur[i]+=(<<(n-j));
}
}
memset(dp,,sizeof(dp));
for(int i=; i<=top; i++)
{
num[i]=icount(state[i]);
if(fit(state[i],))
dp[][][i]=num[i];
}
for(int i=; i<=m; i++)
{
for(int t=; t<=top; t++)
{
if(!fit(state[t],i)) continue;//符合本行
for(int j=; j<=top; j++)
{
if(state[j]&state[t]) continue;//符合上一行
for(int k=; k<=top; k++) //符合上上行
{
if(state[k]&state[t]) continue;
if(state[k]&state[j]) continue;
dp[i][j][t]=max(dp[i][j][t],(dp[i-][k][j]+num[t]));
}
}
}
}
int maxx=-;
for(int i=; i<=m; i++)
{
for(int j=; j<=top; j++)
{
for(int k=; k<=top; k++)
{
maxx=max(maxx,dp[i][j][k]);
}
}
}
printf("%d\n",maxx);
}
return ;
}

POJ1185:炮兵阵地(状压dp)的更多相关文章

  1. POJ1185 炮兵阵地 —— 状压DP

    题目链接:http://poj.org/problem?id=1185 炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions ...

  2. poj1185 炮兵阵地 状压dp

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

  3. TZOJ 4912 炮兵阵地(状压dp)

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

  4. 洛谷P2704 [NOI2001]炮兵阵地 [状压DP]

    题目传送门 炮兵阵地 题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图 ...

  5. [POJ1185][NOI2001]炮兵阵地 状压DP

    题目链接:http://poj.org/problem?id=1185 很裸的状压,考虑对于一行用二进制储存每一种的状态,但是状态太多了做不了. 观察到有很多状态都是不合法的,于是我们预处理出合法的状 ...

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

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

  7. luogu 2704 炮兵阵地 状压dp

    状压的基础题吧 第一次看感觉难上天,后来嘛就.. 套路:先根据自身状态筛出可行状态,再根据地图等其他限制条件筛选适合的状态加入答案 f i,j,k 分别代表 行数,本行状态,上行状态,再累加答案即可 ...

  8. POJ 1185 炮兵阵地 状压dp

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

  9. [NOI2001]炮兵阵地 状压DP

    题面: 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图.在每一格平原地形上最多 ...

  10. 炮兵阵地 /// 状压DP oj26314

    题目大意: 炮兵阵地 设置炮兵的位置 其上两位 下两位 左两位 右两位 不能同时设置炮兵 这题是 corn fields玉米地 的升级版 可以先看下这题的注释 更详细些 第一种方法是网上大多数题解的解 ...

随机推荐

  1. 一个通用的JavaScript分页

    1.JavaScript代码 Pagination=function(id) { var totalNum=0; var maxNum=10; var pageUrl=""; va ...

  2. notepad++程序员开发插件

    1. sftp 2. explore 3. XBrackets 括号自动补全(引号,方括号)

  3. php中判断一个字符是否在字符串中

    strpos() - 查找字符串在另一字符串中第一次出现的位置(区分大小写) stripos() - 查找字符串在另一字符串中第一次出现的位置(不区分大小写) strrpos() - 查找字符串在另一 ...

  4. 解决myeclipse启动慢的问题

    去掉拼写检查:windows->preferences->General->Editors->Text Editors->Spelling 将"Enable s ...

  5. MyBitis(iBitis)系列随笔之二:类型别名(typeAliases)与表-对象映射(ORM)

    类型别名(typeAliases):     作用:通过一个简单的别名来表示一个冗长的类型,这样可以降低复杂度.    类型别名标签typeAliases中可以包含多个typeAlias,如下 < ...

  6. 使用spring + ActiveMQ 总结

    使用spring + ActiveMQ 总结   摘要 Spring 整合JMS 基于ActiveMQ 实现消息的发送接收 目录[-] Spring 整合JMS 基于ActiveMQ 实现消息的发送接 ...

  7. 配置linux的环境变量

    下面是配置linux的环境变量:(记得source .bash_profile). 修改/etc/profile文件 (全局所有用户) vi 此文件/etc/profile在profile文件末尾加入 ...

  8. VC++ 监视文件(夹)

    参考:http://www.cnblogs.com/fangkm/archive/2009/03/31/1426526.html WinFileSystemMonitor.h  C++ Code  1 ...

  9. shell脚本学习总结08--比较与测试

    程序中流程控制是由比较语句和测试语句处理的 算数比较 [ $var -gt 20 ] [ $var -gt 20 -a $var -lt 50 ]         #使用逻辑与 [ $var -ne ...

  10. Android测试:从零开始2——local单元测试

    上一篇分析了android项目的测试分类,这一篇讲local单元测试. 参考android官方文档. 测试前需要配置测试环境,新建项目后,目录下会出现app/src/test/java/文件夹,这个文 ...