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个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八 ...
随机推荐
- HUE的安装
HUE: Hadoop User Experience 官网地址:http://gethue.com/ Hue官网无法下载,超时. 使用CDH版本安装. 下载地址: http://archive.cl ...
- WFP loading 窗口显示 SplashScreen
public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { Spl ...
- 12、JAVA内存模型与线程
一.JMM 有序性,可见性,原子性 synchorize :3个性都有: volatile:保证可见性+禁止指令重排: 二.线程的五种状态 面向过程与面向对象的差别 面向过程:站在计算机的角度分析和解 ...
- Hadoop日记Day13---使用hadoop自定义类型处理手机上网日志
测试数据的下载地址为:http://pan.baidu.com/s/1gdgSn6r 一.文件分析 首先可以用文本编辑器打开一个HTTP_20130313143750.dat的二进制文件,这个文件的内 ...
- CodeForces 1073F Choosing Two Paths
Description You are given an undirected unweighted tree consisting of \(n\) vertices. An undirected ...
- [LOJ#6033]. 「雅礼集训 2017 Day2」棋盘游戏[二分图博弈、匈牙利算法]
题意 题目链接 分析 二分图博弈经典模型,首先将棋盘二分图染色. 考虑在某个最大匹配中: 如果存在完美匹配则先手必败,因为先手选定的任何一个起点都在完美匹配中,而后手则只需要走这个点的匹配点,然后先手 ...
- Mysql + Mybatis动态建表
service层业务 package com.zx.common.service.impl; import com.zx.common.entity.SysUser; import com.zx.co ...
- linux之 sed 基础
转载:https://www.cnblogs.com/chensiqiqi/p/6382080.html sed 介绍 Sed命令是操作,过滤和转换文本内容的强大工具.常用功能有增删改查(增加,删除, ...
- 粒子群算法(PSO)算法解析(简略版)
粒子群算法(PSO) 1.粒子群算法(PSO)是一种基于群体的随机优化技术: 初始化为一组随机解,通过迭代搜寻最优解. PSO算法流程如图所示(此图是从PPT做好,复制过来的,有些模糊) 2.PSO模 ...
- IT简历
对很多IT毕业生来说,写简历投简历是必不可少的.一个好的简历已是面试成功的一半. 简历的目的是为了引人注意,争取让HR主动联系你去面试,不可避免的在简历中掺杂着一些水分,但是能争取到面试机会,再与HR ...