炮兵阵地
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 21366   Accepted: 8280

Description

司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队。一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图。在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队);一支炮兵部队在地图上的攻击范围如图中黑色区域所示: 




如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格。图上其它白色网格均攻击不到。从图上可见炮兵的攻击范围不受地形的影响。 

现在,将军们规划如何部署炮兵部队,在防止误伤的前提下(保证任何两支炮兵部队之间不能互相攻击,即任何一支炮兵部队都不在其他支炮兵部队的攻击范围内),在整个地图区域内最多能够摆放多少我军的炮兵部队。 

Input

第一行包含两个由空格分割开的正整数,分别表示N和M; 

接下来的N行,每一行含有连续的M个字符('P'或者'H'),中间没有空格。按顺序表示地图中每一行的数据。N <= 100;M <= 10。

Output

仅一行,包含一个整数K,表示最多能摆放的炮兵部队的数量。

Sample Input

5 4
PHPP
PPHH
PPPP
PHPP
PHHP

Sample Output

6

这道状态DP折磨了我相当久的时间,做的时候又花了一个下午找WA原因在哪。

首先,自己做麻烦的第一点在于 a&b 两个十进制的数本身就可以判断两列是否有炮兵对打,而不用像我一开始想象的把十进制转成二进制,再用二进制进行判断,这个已经帮你弄好了。

第二点,本身状态也没有那么多。最多是1024个,再加上用if((i&i<<1)||(i&i<<2)) (这个判断简直了)之后就剩了大概六十个左右好像是。所以将这些合理的状态记录下来,这样的思路就能够想到了。

第三点,判断状态 哪一行是属于第几个状态,这点也很好。

剩下的就是状态dp自己的事了,什么这一行的值只和前两行有关什么的。

总之,这道题真的很好,很值得琢磨。

代码:

#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#pragma warning(disable:4996)
using namespace std; int hang[110];//hang[i]表示第i行的初始状态
int state[80];//
int solider[80];
int dp[110][80][80];
int row,col,i,j,k,h,he;
char pb_state[15]; int main()
{
cin>>row>>col; memset(hang,0,sizeof(hang));
memset(dp,0,sizeof(dp));
memset(solider,0,sizeof(solider));
memset(state,0,sizeof(state)); for(i=1;i<=row;i++)
{
cin>>pb_state;
for(j=0; j<col; j++)
if(pb_state[j]=='H') hang[i]+=1<<j;
} he=1;
for(i=0;i<(1<<col);i++)
{
if((i&i<<1)||(i&i<<2)) continue;
state[he]=i;
int temp=i,num=0;
while(temp)
{
num += temp&1;
temp=temp>>1;
}
solider[he]=num;
he++;
}
for(i=1;i<he;i++)
{
if(state[i]&hang[1])continue;
dp[1][i][0]= solider[i];
}
for(i=1;i<he;i++)
{
if(state[i]&hang[2])continue;
for(j=1;j<he;j++)
{
if(state[i]&state[j])continue;
if(state[j]&hang[1]) continue;
dp[2][i][j]=max(dp[2][i][j],dp[1][j][0]+solider[i]);
}
}
for(h=3;h<=row;h++)
{
for(i=1;i<he;i++)//
{
if(state[i]&hang[h])continue;
for(j=1;j<he;j++)
{
if(state[j]&hang[h-1])continue;
if(state[j]&state[i])continue;
for(k=1;k<he;k++)
{
if(state[k]&hang[h-2])continue;
if(state[k]&state[i])continue;
if(state[k]&state[j])continue; dp[h][i][j]=max(dp[h][i][j],dp[h-1][j][k]+solider[i]);
}
}
}
}
int ans=0;
for(i=1;i<he;i++)
for(j=0;j<he;j++)//!!!注意啊,这里一定是从0开始的,因为之前设置好的就是0啊。。。。。。。。。。。。。。。。。。
ans=max(ans,dp[row][i][j]);
cout<<ans<<endl;
//system("pause");
return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

POJ 1185:炮兵阵地的更多相关文章

  1. POJ 1185 炮兵阵地 状压dp

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

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

    炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 26426   Accepted: 10185 Descriptio ...

  3. POJ 1185 炮兵阵地(动态规划+状态压缩)

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

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

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

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

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

  6. POJ 1185 炮兵阵地 经典的 状态压缩dp

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

  7. POJ 1185 - 炮兵阵地 & HDU 4539 - 郑厂长系列故事——排兵布阵 - [状压DP]

    印象中这道题好像我曾经肝过,但是没肝出来,现在肝出来了也挺开心的 题目链接:http://poj.org/problem?id=1185 Time Limit: 2000MS Memory Limit ...

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

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

  9. poj 1185 炮兵阵地(三维状态压缩dP)

    题目:http://poj.org/problem?id=1185 思路: d[i][j][k]表示第i行的状态为第k个状态,第i-1行的状态为第j个状态的时候 的炮的数量. 1表示放大炮, 地形状态 ...

  10. poj -1185 炮兵阵地 (经典状压dp)

    http://poj.org/problem?id=1185 参考博客:http://poj.org/problem?id=1185 大神博客已经讲的很清楚了,注意存状态的时候是从1开始的,所以初始化 ...

随机推荐

  1. 分布估计算法解决TSP问题

    分布估计算法解决旅行商问题(TSP) TSP问题(Traveling Salesman Problem,旅行商问题),由威廉哈密顿爵士和英国数学家克克曼T.P.Kirkman于19世纪初提出.问题描述 ...

  2. Ajax--数据格式

    1.从服务端接收数据的时候,那些数据必须以浏览器能够理解的格式来发送,服务器端的编程语言智能以如下三种格式返回数据:1)XML; 2)JSON; 3)HTML; 2.解析HTML: --HTML由一些 ...

  3. JDBC--调用函数&存错过程

    1.通过Connection对象的prepareCall()方法创建CallableStatement对象的实例,在使用prepareCall()方法时需传入一个String类型的字符串,该字符串用于 ...

  4. modelsim10.4环境变量的设置

    在用户变量中设置,注意路径还要包括license.txt 点击高级属性设置 点击环境变量 在用户变量一件名为:MGLS_LICENSE_FILE的变量 点击确定

  5. Python Download Image (python + requests + BeautifulSoup)

    环境准备 1 python + requests + BeautifulSoup 页面准备 主页面: http://www.netbian.com/dongman/ 图片伪地址: http://www ...

  6. ZC706+FMCOMMS5应用笔记

    1.板载时钟配置. ZC706有200MHz LVDS差分时钟源SiT9102,作为ZYNQ系统参考时钟. COMMS5板子上有ADCLK846时钟Buffer分路器作为AD9361的时钟源,AD84 ...

  7. 2.15 学习总结 之 天气预报APP volley(HTTP库)之StringRequest

    一.说在前面   昨天 学习了序列化的相关知识   今天 1.学习 volley(HTTP库)的 StringRequest请求 2.使用序列化完成相关案例 遇到问题 请求到的参数的出现中文乱码问题 ...

  8. CC3200 飞行计划

    CC3200 飞行计划 2016-01-25 CC3200 资源 CC3200_JTAG调试 CC3200-Uniflash 烧写程序 Mosquitto搭建MQTT 服务器 [示例] CC3200_ ...

  9. 冰蝎动态二进制加密WebShell基于流量侧检测方案

    概述 冰蝎是一款新型动态二进制加密网站工具.目前已经有6个版本.对于webshell的网络流量侧检测,主要有三个思路.一:webshell上传过程中文件还原进行样本分析,检测静态文件是否报毒.二:we ...

  10. 关于Android 的内存泄露及分析(转)

    一. Android的内存机制Android的程序由Java语言编写,所以Android的内存管理与Java的内存管理相似.程序员通过new为对象分配内存,所有对象在java堆内分配空间:然而对象的释 ...