这个题目是个挺难表示的状态DP,因为不但要考虑上下还要考虑左右,在DP里面就没有什么下了咯,但也至少除了考虑左右还要考虑上

所以先枚举出在同一行满足条件的状态 即 某状态 若 s&(s<<1) 或者(s&(s<<2)) 则说明同一行的炮塔在射击范围内,要去掉。

然后就是考虑不同行的了,只要上一行和上上行的状态不冲突即可

于是就有了如下状态

dp[i][j][k]代表第i行状态为k,上一行的状态为j时的最大值。

于是它的子状态就是 dp[i-1][w][j]代表上一行的状态为j 上上行的状态为w的最大值。

于是 dp[i][j][k]=max(dp[i][j][k],dp[i-1][w][j]+calc[k]) (calc代表某个状态中1的个数 即炮塔的数目)。

需要枚举四层循环 中间通过状态的对比来去掉一些没用的状态。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 11
using namespace std;
int dp[105][<<N-][<<N-];
int A[105],m,n,calc[<<N],num,state[<<N];
void init()
{
num=;
for (int i=;i<(<<m);i++)
{
int tmp=;
if (i&(i<<) || i&(i<<)) continue; //左右有冲突 跳过。
state[num]=i;
for (int j=;j<m;j++)
{
if ((<<j)&i)
tmp++;
}
calc[num++]=tmp; //算出某个状态中的含1的个数
}
}
bool fit(int a,int b)//判断上下某个状态是否冲突
{
if (a&b) return ;
return ;
}
void DP()
{
int ans=;
for (int i=;i<num;i++) //先预处理第一行的情况
{
if (!fit(state[i],A[]))
continue;
dp[][][i]=calc[i];
ans=max(ans,dp[][][i]);
}
for (int i=;i<=n;i++)
{
for (int k=;k<num;k++) //这里的是先枚举k还是j 没什么大关系,两个状态彼此独立。
{
for (int j=;j<num;j++)
{
if (!fit(state[j],state[k])|| !fit(state[k],A[i]) || !fit(state[j],A[i-]))//有冲突就直接跳过
continue;
for (int w=;w<num;w++)
{
if (!fit(state[j],state[w])|| !fit(state[k],state[w]))
continue;
if (!fit(state[w],A[i-])) continue;
dp[i][j][k]=max(dp[i][j][k],dp[i-][w][j]+calc[k]);
ans=max(ans,dp[i][j][k]);
}
}
}
}
printf("%d\n",ans);
}
int main()
{
char c; while (scanf("%d%d",&n,&m)!=EOF)
{
init();
memset(dp,,sizeof dp);
for (int i=;i<=n;i++)
{
getchar();
A[i]=;
for (int j=;j<m;j++)
{
c=getchar();
if (c=='H')
A[i]+=<<j; //这里故意把H设置为1,是为了正好用上面的fit函数,如果有状态把炮塔建在H上,就是不可取的状态。
// cout<<c;
}
// cout<<endl;
}
DP(); }
return ;
}

POJ 1185 状态DP的更多相关文章

  1. POJ 1185 状态压缩DP 炮兵阵地

    题目直达车:   POJ 1185 炮兵阵地 分析: 列( <=10 )的数据比较小, 一般会想到状压DP. Ⅰ.如果一行10全个‘P’,满足题意的状态不超过60种(可手动枚举). Ⅱ.用DFS ...

  2. POJ 1185 状态压缩DP(转)

    1. 为何状态压缩: 棋盘规模为n*m,且m≤10,如果用一个int表示一行上棋子的状态,足以表示m≤10所要求的范围.故想到用int s[num].至于开多大的数组,可以自己用DFS搜索试试看:也可 ...

  3. poj 1185 状态压缩

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

  4. poj 1185(状态压缩DP)

    poj  1185(状态压缩DP) 题意:在一个N*M的矩阵中,‘H'表示不能放大炮,’P'表示可以放大炮,大炮能攻击到沿横向左右各两格,沿纵向上下各两格,现在要放尽可能多的大炮使得,大炮之间不能相互 ...

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

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

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

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

  7. POJ 3254 压缩状态DP

    题意:一个矩形网格,可以填0或1, 但有些位置什么数都不能填,要求相邻两个不同时为1,有多少种填法.矩形大小最大 12*12. 压缩状态DP大多有一个可行的state的范围,先求出这个state范围, ...

  8. 【简●解】POJ 1185,LG P2704【炮兵阵地】

    POJ 1185,LG P2704[炮兵阵地] 状压经典入门. [传送门] POJ 1185 洛谷 P2704 [题目大意] 司令部的将军们打算在 \(N\times M\) 的网格地图上部署他们的炮 ...

  9. hdu 4614 pieces 状态DP

    题意:给你一个长度小于等于16的字符串,每次可以删除一个回文传,问你最少删除干净的字数. 状态+dp dp[i] = min(dp[i],dp[j]+dp[j^i]);(j是i的字串): 连接:htt ...

随机推荐

  1. 04.Delphi通过接口IInterface实现多重继承

    IInterface表示申明了一些函数,自己本身没有实现部分,需要由继承它的类来实现函数 uSayHello代码如下 unit uSayHello; interface uses SysUtils, ...

  2. 数据库连接需要dll

    连接oracle引用: Oracle.ManagedDataAccess.dll和Oracle.ManagedDataAccess.EntityFramework.dll, 连接sqlserver 连 ...

  3. leetcode817 Linked List Components

    """ We are given head, the head node of a linked list containing unique integer value ...

  4. B - Stacks of Flapjacks UVA - 120

    BackgroundStacks and Queues are often considered the bread and butter of data structures and find us ...

  5. CAN网络上新增加的设备与网络上已有设备MAC地址冲突的软件解决方案

    已知 1号的CAN节点的地址是0x1f 2号的CAN 节点的地址是0x1f 要达到的要求是 假设 网络上 CAN1 节点已经工作了,我现在需要在网络上接入CAN2节点. 那么CAN2节点首次上电的时候 ...

  6. 说说我当初是如何学Linux的

    今天我就说说我当初是如何从一名普通桌面维护工程师,通过学习和努力转成Linux运维工程师的,以及作为Linux运维工程师需要一些什么技能和知识,希望可以帮到一些对Linux有兴趣或者想往Linux这个 ...

  7. excel处理经纬度

    =LEFT(A1,FIND("°",A1)-1)*1+MID(A1,FIND("°",A1)+1,2)/60+MID(A1,FIND("′" ...

  8. ubuntu18.04 基于Hadoop3.1.2集群的Hbase2.0.6集群搭建

    前置条件: 之前已经搭好了带有HDFS, MapReduce,Yarn 的 Hadoop 集群 链接: ubuntu18.04.2 hadoop3.1.2+zookeeper3.5.5高可用完全分布式 ...

  9. 错误:selenium.common.exceptions.SessionNotCreatedException: Message: Unable to find a matching set of capabilities

    错误再现 原因:firefox浏览器版本和浏览器驱动版本不匹配 解决办法:卸载高版本浏览器,安装低版本浏览器

  10. CV_图像滤波[转]---python+opencv均值滤波,高斯滤波,中值滤波,双边滤波

    1.图像滤波算法(cv2) https://blog.csdn.net/qq_27261889/article/details/80822270 2.