dp乱写1:状态压缩dp(状压dp)炮兵阵地
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)炮兵阵地的更多相关文章
- 状态压缩动态规划 状压DP
总述 状态压缩动态规划,就是我们俗称的状压DP,是利用计算机二进制的性质来描述状态的一种DP方式 很多棋盘问题都运用到了状压,同时,状压也很经常和BFS及DP连用,例题里会给出介绍 有了状态,DP就比 ...
- 状态压缩动态规划(状压DP)详解
0 引子 不要999,也不要888,只要288,只要288,状压DP带回家.你买不了上当,买不了欺骗.它可以当搜索,也可以卡常数,还可以装B,方式多样,随心搭配,自由多变,一定符合你的口味! 在计算机 ...
- hihoCoder 1044 : 状态压缩·一 状压dp
思路:状态压缩,dp(i, j)表示考虑前i个数且[i-m+1, i]的选择情况为j.如果要选择当前这个数并且,数位1的个数不超过q,则dp[i+1][nex] = max(dp[i+1][nex], ...
- hihocoder #1044 : 状态压缩·一 状压DP
http://hihocoder.com/problemset/problem/1044 可以看出来每一位的选取只与前m位有关,我们把每个位置起始的前m位选取状态看出01序列,就可以作为一个数字来存储 ...
- 【bzoj3195】【 [Jxoi2012]奇怪的道路】另类压缩的状压dp好题
(上不了p站我要死了) 啊啊,其实想清楚了还是挺简单的. Description 小宇从历史书上了解到一个古老的文明.这个文明在各个方面高度发达,交通方面也不例外.考古学家已经知道,这个文明在全盛时期 ...
- 有关状压DP
[以下内容仅为本人在学习中的所感所想,本人水平有限目前尚处学习阶段,如有错误及不妥之处还请各位大佬指正,请谅解,谢谢!] 引言 动态规划虽然已经是对暴力算法的优化,但在某些比较特别的情况下,可以通过一 ...
- 【状压DP】bzoj1087 互不侵犯king
一.题目 Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上.下.左.右,以及左上.左下.右上.右下八个方向上附近的各一个格子,共8个格子. I ...
- 状压dp(总结)状态压缩
状压这个和二进制分不开关系 所以,对于二进制的熟悉是必不可少的技能 & 与操作,1不变,0变0 | 或操作,0不变,1变1 ^ 异或操作,0不变,1取反 - 取反操作,把每一个二进制位0 ...
- 状压DP学习笔记
有的时候,我们会发现一些问题的状态很难直接用几个数表示,这个时候我们就会用到状压dp啦~~. 状压就是状态压缩,就是讲原本复杂难以描述的状态用一个数或者几个数来表示qwq.状态压缩是一个很常用的技巧, ...
- 互不侵犯_状压$dp$
如果有想学习状压\(dp\)的童鞋,请光临博客状压\(dp\)初学 互不侵犯 题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八 ...
随机推荐
- plsql命令行窗口执行脚本打印输出
1.我们可以写一些简单的检查数据库的检查脚本 prompt Importing table t_test0... set feedback off set define off ; ; prompt ...
- 基于TLS证书手动部署kubernetes集群(下)
一.master节点组件部署 承接上篇文章--基于TLS证书手动部署kubernetes集群(上),我们已经部署好了etcd集群.flannel网络以及每个节点的docker,接下来部署master节 ...
- 20155227辜彦霖《基于Cortex-M4的UCOSIII的应用》课程设计个人报告
20155227辜彦霖<基于Cortex-M4的UCOSIII的应用>课程设计个人报告 一.个人贡献 参与课设题目讨论及完成全过程: 资料收集: 负责主要代码调试: 撰写小组结题报告. 二 ...
- Android开发——Android多进程以及使用场景介绍
个层级,具体可以查看Android开发--Android进程保活招式大全中1.1部分的内容,这里就不赘述了. 根据进程中当前活动组件的重要程度,Android 会将进程评定为它可能达到的最高级别.例如 ...
- ActiveMQ 的安装与使用(springboot版本)
一.安装 上官网下载tar包 http://activemq.apache.org/ tar -zxvf 后进入bin/linux-86-64 ./activimq start 启动 二.使用 pom ...
- POJ2531&&1416&&2676&&1129
搜索专题的最后一块了,也告别了这些老的东西了 接下来就是些全新的内容了啊! 这次的标签是简单搜索技巧和剪枝,也就是优化爆搜 当然,像Dancing links这样的玄学操作还是没有的 2531 题意: ...
- [CTSC2006]歌唱王国
[CTSC2006]歌唱王国 Tags:题解 题意 链接:在空串后不断随机添加字符,直到出现串\(S_i\)为止.求最终串的期望长度.\(\sum |S_i|\le 5*10^6\) 题解 以下内容来 ...
- 初入Installshield2015
首先我们来认识一下这款软件:这是一款功能强大的软件打包工具,有着许多强大的功能等着我们去发掘,博主也是最近被这个东西搞得有点晕头, 现在就想让读者朋友们更快的接受这个软件. 这个软件需要的破解工具,大 ...
- Java收发邮件过程中具体的功能是怎么实现的
SMTP协议 用户连上邮件服务器后,要想给它发送一封电子邮件,需要遵循一定的通迅规则,SMTP协议就是用于定义这种通讯规则的. 因而,通常我们也把处理用户smtp请求(邮件发送请求)的邮件服务器称之为 ...
- 20135202闫佳歆--week4 系统调用(上)--学习笔记
此为个人笔记存档 week 4 系统调用(上) 一.用户态.内核态和中断处理过程 用户通过库函数与系统调用联系起来. 1.内核态 在高执行级别下,代码可以执行特权指令,访问任意的物理地址. 2.用户态 ...