https://www.luogu.org/problem/show?pid=2704

题意:

炮兵在地图上的摆放位子只能在平地('P')

炮兵可以攻击上下左右各两格的格子;

而高原('H')上炮兵能够攻击到但是不能摆放

求最多能摆放的炮兵的数量

就是这个意思。

难度提高,弱省省选

一开始是想写dfs(迷之八皇后)的,

但是看到数据量100就想dp了;

因为题目n的范围给的很少n<=10,想到状压

非常明显是一个状态压缩的dp(状压dp)

其实可以当做状压的入门题目来做。

由于本行的状态是由前若干行推出来的,所以想到了从上推到下(而不是从左推到右)

还有,本行的状态与前1行,前2行的状态密切相关的(炮兵不互相攻击)

写出我们dp的状态:f[i,r1j]表示当前第i行状态为j,i-1行状态为r1的炮兵数

转移其实就是非常简单了:(r2就是前第2行的状态)

f[i,r1,j]:=max(f[i,r1,j],f[i-1,r2,r1]+sum[j]);

转移的条件:r1和r2不与H有一个重合;r1和r2不能被互相打到或达j

本题主要难在处理dp初始化的方面;

首先我们需要保证每一种拓展出来的炮兵排列的方式需要在该行中横向不互相攻击;

这种每行不攻击的序列总数小于等于60;

pd函数非常好写:

function pd(x:longint):boolean;//判断此时放的是否合法(附近两位不能有1)
begin
if (x and (x<<))<> then exit(false);
if (x and (x<<))<> then exit(false);
exit(true);
end;

引入col[i]的二进制数组,表示第i行‘H’的分布 if s[j]='H' then col[i]:=col[i] or (1<<(j-1));

注意这里需要j-1,因为二进制是从2^0开始的。

注意初始化第0行所有地点都是高山,由于第0行可能会影响第2行;

特殊处理第一行:(st数组保存所有合法的序列,cnt为合法序列的个数,st标号1~cnt)

for i:= to cnt do begin
if (col[] and st[i])= then f[,,i]:=sum[i];
end;

所以,本题的代码简单,主要注意的是初始值和dp式不要写错(4维的转移,暴力)

uses math;
var n,m,i,j,r1,r2,ans,cnt:longint;
f:array[..,..,..]of longint;
//f[i,j,k]表示当前第i行状态为j,i-1行状态为k的炮兵数
s:string;
st,sum,col:array[..]of longint;
function pd(x:longint):boolean;//判断此时放的是否合法(附近两位不能有1)
begin
if (x and (x<<))<> then exit(false);
if (x and (x<<))<> then exit(false);
exit(true);
end;
function getbit(x:longint):longint;//求出二进制数x中有几个1
var sum:longint;
begin
sum:=;
while x> do begin
if (x and )= then inc(sum);
x:=x>>;
end;
exit(sum);
end;
procedure getdp(m:longint);
var e,i:longint;
begin
e:=<<m;
cnt:=;
for i:= to e- do
if pd(i) then begin
inc(cnt);
st[cnt]:=i; //保存此时的状态
sum[cnt]:=getbit(i); //炮兵的个数
end;
end;
begin
readln(n,m);
getdp(m);
fillchar(col,sizeof(col),);
for i:= to m do col[]:=col[] or (<<i);
for i:= to n do begin
readln(s);
for j:= to m do
if s[j]='H' then col[i]:=col[i] or (<<(j-));
end;
//col[i]表示第i行高地的分布
fillchar(f,sizeof(f),);//clear!
for i:= to cnt do begin
if (col[] and st[i])= then f[,,i]:=sum[i];
end;
for i:= to n do
for j:= to cnt do //现在这行的状态是j
if (col[i] and st[j])= then
for r1:= to cnt do //上一行状态是r1
if (st[j] and st[r1])= then
for r2:= to cnt do //上上行的状态是r2
if (st[j] and st[r2])= then
if f[i-,r2,r1]<>- then
f[i,r1,j]:=max(f[i,r1,j],f[i-,r2,r1]+sum[j]);
ans:=;
for i:= to cnt do
for j:= to cnt do
ans:=max(ans,f[n,i,j]);
writeln(ans);
end.

dp乱写1:状态压缩dp(状压dp)炮兵阵地的更多相关文章

  1. 状态压缩动态规划 状压DP

    总述 状态压缩动态规划,就是我们俗称的状压DP,是利用计算机二进制的性质来描述状态的一种DP方式 很多棋盘问题都运用到了状压,同时,状压也很经常和BFS及DP连用,例题里会给出介绍 有了状态,DP就比 ...

  2. 状态压缩动态规划(状压DP)详解

    0 引子 不要999,也不要888,只要288,只要288,状压DP带回家.你买不了上当,买不了欺骗.它可以当搜索,也可以卡常数,还可以装B,方式多样,随心搭配,自由多变,一定符合你的口味! 在计算机 ...

  3. hihoCoder 1044 : 状态压缩·一 状压dp

    思路:状态压缩,dp(i, j)表示考虑前i个数且[i-m+1, i]的选择情况为j.如果要选择当前这个数并且,数位1的个数不超过q,则dp[i+1][nex] = max(dp[i+1][nex], ...

  4. hihocoder #1044 : 状态压缩·一 状压DP

    http://hihocoder.com/problemset/problem/1044 可以看出来每一位的选取只与前m位有关,我们把每个位置起始的前m位选取状态看出01序列,就可以作为一个数字来存储 ...

  5. 【bzoj3195】【 [Jxoi2012]奇怪的道路】另类压缩的状压dp好题

    (上不了p站我要死了) 啊啊,其实想清楚了还是挺简单的. Description 小宇从历史书上了解到一个古老的文明.这个文明在各个方面高度发达,交通方面也不例外.考古学家已经知道,这个文明在全盛时期 ...

  6. 有关状压DP

    [以下内容仅为本人在学习中的所感所想,本人水平有限目前尚处学习阶段,如有错误及不妥之处还请各位大佬指正,请谅解,谢谢!] 引言 动态规划虽然已经是对暴力算法的优化,但在某些比较特别的情况下,可以通过一 ...

  7. 【状压DP】bzoj1087 互不侵犯king

    一.题目 Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上.下.左.右,以及左上.左下.右上.右下八个方向上附近的各一个格子,共8个格子. I ...

  8. 状压dp(总结)状态压缩

    状压这个和二进制分不开关系 所以,对于二进制的熟悉是必不可少的技能 &  与操作,1不变,0变0 |  或操作,0不变,1变1 ^  异或操作,0不变,1取反 - 取反操作,把每一个二进制位0 ...

  9. 状压DP学习笔记

    有的时候,我们会发现一些问题的状态很难直接用几个数表示,这个时候我们就会用到状压dp啦~~. 状压就是状态压缩,就是讲原本复杂难以描述的状态用一个数或者几个数来表示qwq.状态压缩是一个很常用的技巧, ...

  10. 互不侵犯_状压$dp$

    如果有想学习状压\(dp\)的童鞋,请光临博客状压\(dp\)初学 互不侵犯 题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八 ...

随机推荐

  1. 微服务 Rpc和Rest协议

    原文:https://blog.csdn.net/king866/article/details/54174665 接口调用通常包含两个部分,序列化和通信协议.常见的序列化协议包括json.xml.h ...

  2. 使用MySQL命令行修改密码

    格式:mysqladmin -u用户名 -p旧密码 password 新密码 1.给root加个密码ab12.首先在DOS下进入目录mysql\bin,然后键入以下命令    mysqladmin - ...

  3. # 2017-2018-2 20155231《网络对抗技术》实验九: Web安全基础实践

    2017-2018-2 20155231<网络对抗技术>实验九: Web安全基础实践 实验要求: 本实践的目标理解常用网络攻击技术的基本原理.Webgoat实践下相关实验. 实验内容: ( ...

  4. Photoshop CS4破解方法

    先在网上下载Photoshop CS4的版本,安装后按如下步骤操作即可. 激活码: 1330-1082-3503-2270-3738-6738 1330-1776-8671-6289-7706-291 ...

  5. C# Language Specification 5.0 (翻译)第四章 类型

    C# 语言的类型分为两大类:值类型(value type)和引用类型(reference type),而它们又都同时具有至少一个类型形参的泛型类型(generic type).类型形参(type pa ...

  6. MyBatis的一级缓存和二级缓存简介笔记

    关于mybatis中一级缓存和二级缓存的简单介绍 mybatis的一级缓存: MyBatis会在表示会话的SqlSession对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,当下次查询的时候 ...

  7. 设计模式 笔记 适配器模式 Adapter

    //---------------------------15/04/13---------------------------- //Adapter 适配器模式 ----类对象结构型模式 /* 1: ...

  8. Hadoop框架

    1.Hadoop的整体框架 Hadoop由HDFS.MapReduce.HBase.Hive和ZooKeeper等成员组成,其中最基础最重要元素为底层用于存储集群中所有存储节点文件的文件系统HDFS( ...

  9. ping命令使用及其常用参数

    PING (Packet Internet Groper),因特网包探索器,用于测试网络连接量检查网络是否连通,可以很好地帮助我们分析和判定网络故障.Ping发送一个ICMP(Internet Con ...

  10. PAT甲题题解-1036. Boys vs Girls (25)-找最大最小,大水题

    题意:给出n个人的姓名.性别.ID.分数,让你找出其中哪个妹纸分数最高.哪个汉子分数最低.以及他们的差如果没有妹纸或者汉子,则对应输出Absent,差用NA代替. 就是for一遍找最大最小值,水题 # ...