炮兵阵地
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 31718   Accepted: 12253

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

题意:中文题面,题意很明显了
我们来考虑一下最暴力的搜索每个点都尝试一遍的话会是1000!
肯定是会爆炸的,所以,既然每行的列数在10以内,那么我们很自然的就想到了状态压缩的dp
将每一行的状态存储为一个二进制数,1表示可以放,0表示不能放
每一层的状态由上一层推导而来,如果上层这个地方放了,那么下面的这个地方就不能放
所以我们要用到二进制的位运算

dp[r][j][i]=max(dp[r−1][k][j]+sum[i])

其中sum[i]sum[i]为i状态对应的数量

代码如下:

(参考上海全能王博客

http://cubercsl.cn/solve/2017-summer/emplacement/

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <stack>
using namespace std;
const int maxn =;
const int INF = 0x3f3f3f3f;
const int mod = 1e9+;
const double eps = 1e-;
int dp[maxn][maxn][maxn];
int maze[maxn];
vector<int> v,sum;
inline bool ok(int s){
return !(s&(s<<))&&!(s&(s<<));
}
inline int getsum(int s){
int ret=;
for(;s;s>>=){
if(s&) ret++;
}
return ret;
}
void init(int m){
for(int i=;i <(<<m);i++){
if(ok(i)){
v.push_back(i);
sum.push_back(getsum(i));
}
}
}
int main(){
int n,m;
char tmp;
cin>>n>>m;
init(m);
memset(dp,0xc0,sizeof(dp));
for(int i=;i<n;i++){
for(int j=;j<m;j++){
cin>>tmp;
if(tmp=='H') maze[i]|=(<<j);
}
}
for(int i=;i<v.size();i++){
if(!(v[i]&maze[])){
dp[][][i]=sum[i];
}
}
for(int r=;r<n;r++)
for(int i=;i<v.size();i++)
if(!(v[i]&maze[r]))
for(int j=;j<v.size();j++)
if(!(v[i]&v[j]))
for(int k=;k<v.size();k++)
if(!(v[i]&v[k]))
dp[r][j][i]=max(dp[r][j][i],dp[r-][k][j]+sum[i]);
int ans=;
for(int i=;i<v.size();i++){
for(int j=;j<v.size();j++){
ans=max(ans,dp[n-][i][j]);
}
}
cout<<ans<<endl;
return ;
}
 

最新文章

  1. Anjs分词器以及关键词抓取使用的方法
  2. document对象
  3. 基于吉日嘎底层架构的Web端权限管理操作演示-菜单模块管理
  4. Codeforces Round #376 (Div. 2) C D F
  5. COSBench性能测试配置--一张图说明一切
  6. CCNA 6.5
  7. repo安装
  8. JS实现滚动条滚到页面距离底部300px时执行事件的方法
  9. Android“This Handler class should be static or leaks might occur”警告的处理方法
  10. Flex 选项卡加载方式简介
  11. [笔记]dynamic gamma correction
  12. Android开发--WIFI实现
  13. APK反编译。
  14. javascript定义类和类的实现
  15. STM32驱动AT24CXX系列芯片
  16. Floyd算法java实现demo
  17. VUE中使用geetest滑动验证码
  18. Mysql笔试题
  19. IO流总结笔记一
  20. Jenkins构建次数设置

热门文章

  1. array_x
  2. 嵌入式框架Zorb Framework搭建二:环形缓冲区的实现
  3. 封装一个ExcelHelper,方便将Excel直接转成Datatable对象
  4. ora-12154 TNS:&quot;无法处理服务名&quot;的一个解决方法
  5. android中接入twitter进行第三方登录
  6. jmeter-maven-plugin
  7. 单链表无head各种操作及操作实验
  8. 教程|要想Hadoop能够运行Python程序,就要会MRJob
  9. 详解python 局部变量与全局变量
  10. 软工实践 - 第二十八次作业 Beta 冲刺(6/7)