题目链接:https://cn.vjudge.net/contest/276236#problem/B

题目大意:略

 具体思路:和我的上一篇写状压dp的思路差不多,不过就是这个题相当于上一个题的升级版,变成了左右,上下都会有限制,并且限制的步数是2,观察数据范围,如果按照上一个题的话,如果要是计算正确的范围取值的话,肯定会超时,所以我们可以先将所有的满足的情况先筛选出来,就算m取到10,总共的情况也就是60种,这样复杂度就大大的降下来了。

我们可以先预处理第一行和第二行,这样的话,我们就可以直接从第三行进行操作了,如果只是预处理第一行的话,第二行在往上走的时候,会取到第0行,而这一行我们是没有赋值的,所以我们应该预处理第一行和第二行。从第3行就可以直接进行操作了(就因为这个问题搞了一晚上。。。)。

我们开一个三维的dp数组,dp[i][j][k]。i代表的是第i行,j代表的是第i行取了哪种情况,k代表的是第i-1行的取值。

按道理来讲,我们应该一次比较三行的,可是为什么只是处理了两行?

因为我们在处理第i-1行的时候,我们比较的是dp[i-1][k][t]。这里的t是第i-2行,我们在处理第i行的时候就是按照一次比较三行来的,不过第三行的比较是通过第i-2行来进行比较的。

AC代码:

 #include<iostream>
#include<cmath>
#include<stack>
#include<stdio.h>
#include<algorithm>
#include<queue>
using namespace std;
# define inf 0x3f3f3f3f
# define ll long long
const int maxn = +;
char str[maxn];
int a[maxn],ok[maxn],num[maxn];
int dp[maxn][maxn][maxn];
int cal(int t){
int ans=;
while(t){
ans+=(t&);
t>>=;
}
return ans;
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
for(int i=; i<=n; i++)
{
scanf("%s",str+);
for(int j=; j<=m; j++)
{
if(str[j]=='P')
a[i]=(a[i]<<)+;
else
a[i]=(a[i]<<)+;
}
}
int maxstate=(<<m)-;
int ans=;
for(int i=; i<=maxstate; i++)
{
if(((i<<)&i)==&&(((i>>)&i)==)&&(((i>>)&i)==)&&(((i>>)&i)==))//把合理的情况筛选出来。
{
ok[++ans]=i;
num[ans]=cal(i);//记录一下当前的合理情况的能放的炮弹个数记录下来。
}
}
int maxx=;
for(int i=;i<=ans;i++){
if(((ok[i]&a[])==ok[i]))
dp[][i][]=num[i];
maxx=max(maxx,dp[][i][]);
}
for(int i=;i<=ans;i++){
if((ok[i]&a[])==ok[i]){
for(int j=;j<=ans;j++){
if(((ok[j]&ok[i])==)&&((ok[j]&a[])==ok[j])){
dp[][i][j]=max(dp[][i][j],dp[][j][]+num[i]);
maxx=max(maxx,dp[][i][j]);
}
}
}
}
for(int i=;i<=n;i++){
for(int j=;j<=ans;j++){
if((ok[j]&a[i])==ok[j]){
for(int k=;k<=ans;k++){
if(((ok[j]&ok[k])==)&&((ok[k]&a[i-])==ok[k])){
for(int l=;l<=ans;l++){
if(((ok[l]&ok[k])==)&&((ok[l]&ok[j])==)&&((ok[l]&a[i-])==ok[l])){//在枚举第i-2行的时候,还需要和第i行和第i-1行进行比较。
dp[i][j][k]=max(dp[i][j][k],dp[i-][k][l]+num[j]);
maxx=max(maxx,dp[i][j][k]);
}
}
}
}
}
}
}
printf("%d\n",maxx);
return ; }

状压dp(B - 炮兵阵地 POJ - 1185 )的更多相关文章

  1. dp乱写1:状态压缩dp(状压dp)炮兵阵地

    https://www.luogu.org/problem/show?pid=2704 题意: 炮兵在地图上的摆放位子只能在平地('P') 炮兵可以攻击上下左右各两格的格子: 而高原('H')上炮兵能 ...

  2. 状压DP之炮兵阵地

    题目 原题来自:\(NOI 2001\) 司令部的将军们打算在\(N*M\) 的网格地图上部署他们的炮兵部队.一个\(N*M\)的地图由\(N\)行\(M\)列组成,地图的每一格可能是山地(用 H表示 ...

  3. [状压dp]POJ1185 炮兵阵地

    中文题 题意不再赘述 对于中间这个“P” 根据dp的无后效性 我们只需考虑前面的 就变成了 只需考虑: 也就是状压前两行 具体与HDOJ的4539类似: 看HDOJ 4539 仅仅是共存状态的判断不同 ...

  4. 状压DP初识~~炮兵阵地

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

  5. 炮兵阵地 POJ 1185

    n*m P 和 M P可以放人 M不行 人不能相互打到 问最多可以放多少人 #include<stdio.h> #include<algorithm> #include< ...

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

    分析:先枚举出来所有的合法状态(当N=10的时候合法状态最多也就60种),用当前状态匹配上一行和上上一行的状态去匹配,看是否可以.....复杂度100*60*60*60,也可以接受. 代码如下: == ...

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

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

  8. POJ 1185 炮兵阵地 【状压DP】

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

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

    题目链接 题意 : 中文题不详述. 思路 :状压DP,1表示该位置放炮弹,0表示不放.dp[i][j][k],代表第 i 行的状态为k时第i-1行的状态为 j 时放置的最大炮弹数.只是注意判断的时候不 ...

随机推荐

  1. HttpURLConnection、HttpClient和Session

    原文地址:http://www.cnblogs.com/kross/p/3615695.html 一直没弄懂Session,cookies什么的登陆验证到底是怎么回事,昨天分别用HttpURLConn ...

  2. C 语言assert使用

    1.assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行,原型定义:#include <assert.h>void assert( i ...

  3. python的N个小功能(找到要爬取的验证码链接,并大量下载验证码样本)

    # -*- coding: utf-8 -*- """ Created on Mon Mar 21 11:04:54 2017 @author: sl "&qu ...

  4. poj 2185

    http://poj.org/problem?id=2185 题意:求最小的模式块,使其无限扩展后包含给你的矩阵块(看别人题解才懂的题意): 分析:假设存在一个模式块可以满足上述条件,那么必然存在一个 ...

  5. MT【148】凸数列

    (2018浙江省赛13题) 设实数$x_1,x_2,\cdots,x_{2018}$满足$x_{n+1}^2\le x_nx_{n+2},(n=1,2,\cdots,2016)$和$\prod\lim ...

  6. MT【120】保三角函数

    评:1.这里处理第三个函数时用到$ab-a-b=(a-1)(b-1)-1$是处理$ab,a+b$之间加减的常见变形. 2.第二个函数$g(x)=sinx,x\in(0,\frac{5\pi}{6})$ ...

  7. Virtual Table

    C++对象模型——吴泰 C/C++杂记 C++中的虚函数(表)实现机制以及用C语言对其进行的模拟实现 C++ 多继承和虚继承的内存布局 [已翻译100%] (虚继承参考,推荐) 图说C++对象模型:对 ...

  8. PHP中文字符gbk编码与UTF-8编码的转换

    通常PHP中上传文件,如果文件名称有中文字符,上传之后的名称是无法写入到本地的,因为上传来的编码格式一般是UTF-8的格式,这种格式是无法给文件命名并且存储到操作系统磁盘.在写入之前需要将其转换为gb ...

  9. swift网络数据请求方法

    搭建一个apache服务器,用php编写一个返回给客户端请求数据的脚本 <?php // header("Content-type:text/html;charset=utf-8&qu ...

  10. Pentaho的Mondrian对Hive的支持

    需求描述 考虑直接在Hive或者Impala等Big Data方案,能够支持MDX查询,现调研一下Mondrian对hive的支持情况. 环境准备 hive环境,采用hive-0.10-cdh4.2. ...