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. java的myeclipse,java页面改动默认的javadoc方法

    在项目中右键点击新建class文件,在弹出的框中选择"here" 勾上enable project specific settings 选择comments中的types然后点击e ...

  2. 2017-2018-2 20155234『网络对抗技术』Exp5:MSF基础应用

    攻击MS08-067安全漏洞--WindowsXP 在kali输入msfconsole进入控制台,依次输入指令 第一次很遗憾失败了 发现是防火墙没关重新来过成功 攻击MS11-050安全漏洞--IE7 ...

  3. WPF自定义控件的自定义属性绑定后不更新问题

    原文:WPF自定义控件的自定义属性绑定后不更新问题 需要在绑定时设置属性变更触发 UpdateSourceTrigger=PropertyChanged 例如: <Border CornerRa ...

  4. Js读取XML文件为List结构

    习惯了C#的List集合,对于Javascript没有list 极为不舒服,在一个利用Js读取XML文件的Demo中,决定自己构建List对象,将数据存入List. 第一步,Js读取XML文件知识 X ...

  5. koa2 入门(1)koa-generator 脚手架和 mongoose 使用

    项目地址:https://github.com/caochangkui/demo/tree/koa2-learn 1 构建项目 1.1 安装koa-generator $ npm install -g ...

  6. Sleeping会话导致阻塞原理(上)

    背景 我在处理客户问题的时候,客户经常搞不懂sleeping 的由来,和他可能导致的问题.下面来详细说下 什么是sleeping 其实我们经常可以在数据库中看到“”sleeping“状态的连接,但是这 ...

  7. Maven构建项目速度太慢的解决办法

    问题描述 通过idea新建maven项目,参数设置好后,idea自动构建maven项目时,速度很慢. 参数设置如图: 执行时间如下图: Total time为8:49,花了将近十分钟时间. 连续尝试了 ...

  8. 解决coursera无法观看视频的问题

    问题 最近开始看coursera的一个课程,遇到一个问题,可以正常登录网站(未使用VPN),也可以下载资源(除了视频)但是却没有办法在线观看视频. 解决方法 使用VPN 这个方法应该可以解决任何访问国 ...

  9. 【转】Cocos2d-x 3.x基础学习: 总结数学类Vec2/Size/Rect

    转载:http://www.taikr.com/article/1847 在Cocos2d-x 3.x中,数学类Vec2.Size.Rect,是比较常用的类.比如设置图片位置,图片大小,两图片的碰撞检 ...

  10. Mocha 单元测试框架简介

    前言: mocha是JavaScript的一种单元测试框架,既可以在浏览器环境下运行,也可以在Node.js环境下运行. 使用mocha,我们就只需要专注于编写单元测试本身,然后,让mocha去自动运 ...