307-07-逐行递推
本文标题:307-07-逐行递推
文章作者:gyro永不抽风
发布时间:2020年03月01日 - 20:03
最后更新:2020年09月22日 - 20:09
原始链接:http://hexo.gyrojeff.moe/2020/03/01/307-07-%E9%80%90%E8%A1%8C%E9%80%92%E6%8E%A8/
许可协议: 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 转载请保留原文链接及作者!
307-07-逐行递推
逐行递推:$dp$在某种情况下按照一行一行的顺序进行递推。
P2704 [NOI2001]炮兵阵地
题目描述
司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队。一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图。在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队);一支炮兵部队在地图上的攻击范围如图中黑色区域所示:
如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格。图上其它白色网格均攻击不到。从图上可见炮兵的攻击范围不受地形的影响。 现在,将军们规划如何部署炮兵部队,在防止误伤的前提下(保证任何两支炮兵部队之间不能互相攻击,即任何一支炮兵部队都不在其他支炮兵部队的攻击范围内),在整个地图区域内最多能够摆放多少我军的炮兵部队。
输入输出格式
输入格式:
第一行包含两个由空格分割开的正整数,分别表示N和M;
接下来的N行,每一行含有连续的M个字符(‘P’或者‘H’),中间没有空格。按顺序表示地图中每一行的数据。N≤100;M≤10。
输出格式:
仅一行,包含一个整数K,表示最多能摆放的炮兵部队的数量。
题解
这里可以采用逐行递推的方式:定义
$$ f(i,s,t) = \max_{0 ≤ r < 2^m, ~s \&r =0,~t\&r = 0,~s\&t=0,~(r>>1)\&r=0,~(r>>2) = 0, map[i]\&r=0}\{f(i+1, r,s) + count[r]\} $$
其中,$f(i,s,t)$表示在第$i$行,其前一行的炮兵安排表示为$s$,再前一行的炮兵安排表示为$t$的时候的放炮数量(从第$n$行向第$1$行转移,其中$r$表示当前这一行的炮兵按放)。由于每一格上,炮兵只能放或者不放,所以可以表示为一个二进制数。
下面,解释$\max$的条件:
- $0 ≤ r < 2^m$:穷举所有的当前行的炮兵按放可能性
- $s ~\& ~r = 0$:当这一行与上一行没有一列是重复的情况下(取与的操作可以达到这一目的)
- $t~\&~r = 0$:当这一行与上上行没有一列是重复的情况下
- $s~\&~t = 0$:当上一行与上上行没有一列是重复的情况下
- $(r >> 1)~\&~r = 0$:这一行任意一个炮的相邻位置没炮(位移一位就是相邻)
- $(r >> 2)~\& ~r = 0$:这一行任意一个炮的相邻$2$格位置没炮(位移两位就是相邻$2$格)
- $map[i] ~\&~r = 0$:这一行的炮兵安排要与地形匹配
$count[r]$:表示$r$这样的安排会有多少门炮(由于是二进制,换言之就是有几个一)。
由于数组会太大,所以需要滚动数组。
AC代码:
1 |
|
PDF: