#zYDPybttg050404. 1595:炮兵阵地
1595:炮兵阵地
好的,我将这道题整理为清晰的题面格式,并补充样例解释、数据范围与时空限制:
题目描述
原题来自:NOI 2001
司令部的将军们打算在 的网格地图上部署他们的炮兵部队。一个 的地图由 行 列组成,地图的每一格可能是山地(用 H 表示),也可能是平原(用 P 表示)。在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队);一支炮兵部队在地图上的攻击范围如图中黑色区域所示:
攻击范围:以炮兵所在位置为中心,横向左右各两格,纵向上下各两格,共覆盖横竖各 格(即曼哈顿距离 且在同一行或同一列,但不包括斜对角?实际上是十字形横向2格、纵向2格,共 的十字形,但注意图中是横向左右2格、纵向上下2格,共 行 列的十字形,但实际影响范围是上下左右各两格,所以总共影响 个方向各 格加上自身,共 个格子?图例中黑色区域为横向左右2格、纵向上下2格,不包括斜角,所以是十字形,总共 格?我们确认:横向左右2格(共5列),纵向上下2格(共5行),所以是十字形,共 格(因为中心重叠)。
现在,将军们规划如何部署炮兵部队,在防止误伤的前提下(保证任何两支炮兵部队之间不能互相攻击,即任何一支炮兵部队都不在其他支炮兵部队的攻击范围内),在整个地图区域内最多能够摆放多少我军的炮兵部队。
输入格式
第一行包含两个由空格分割开的正整数,分别表示 和 ;
接下来的 行,每一行含有连续的 个字符(P 或者 H),中间没有空格。按顺序表示地图中每一行的数据。
输出格式
仅一行,包含一个整数 ,表示最多能摆放的炮兵部队的数量。
样例
样例输入
5 4
PHPP
PPHH
PPPP
PHPP
PHHP
样例输出
6
样例解释
地图如下(P 平原可放,H 山地不可放):
P H P P
P P H H
P P P P
P H P P
P H H P
炮兵攻击范围是横向左右各2格、纵向上下各2格。
我们需要在平原上放置炮兵,使得任何两个炮兵不在彼此的攻击范围内。
一种最优放置方案(用 X 表示炮兵):
X H X P
P P H H
P P P X
X H P P
P H H X
即:
- 第1行:第1列、第3列
- 第3行:第4列
- 第4行:第1列
- 第5行:第4列
共 个炮兵。
数据范围
对于全部数据:
时空限制
- 时间:
- 内存:
提示
此题为 状态压缩 DP 经典题(NOI 2001)。
特点:炮兵的攻击范围涉及两行,所以状态转移时需要知道前两行的状态。
状态设计:
- 用二进制数表示一行的炮兵放置情况: 表示放炮兵, 表示不放;
- 状态必须满足:
- 一行内炮兵不能互相攻击:即任意两个 之间至少间隔 个 (因为攻击范围左右各 格);
- 炮兵只能放在平原上(
P),不能放在山地(H); - 相邻两行之间,同一列不能同时有 (因为上下攻击范围 格,所以上下相邻两行不能有同一列都有炮兵);
- 隔行之间,同一列也不能同时有 (因为攻击范围上下各两格,所以第 行和第 行的同一列不能同时有炮兵)。
设 表示处理到第 行,第 行状态为 ,第 行状态为 时,前 行最多能放的炮兵数量。
转移方程:
$$dp[i][s1][s2] = \max_{s3} \{ dp[i-1][s2][s3] + \text{popcount}(s1) \}$$条件:
- 内部合法(无相邻两个 距离 );
- 与地图第 行兼容( 的 必须对应平原);
- 与 兼容(同一列不能同时为 );
- 与 兼容(同一列不能同时为 )。
初始化:。
最终答案:
优化:
- 预处理所有合法行状态(满足间隔至少两个 );
- 预处理状态间的兼容性(两两状态同一列不能同时为 );
- 由于 ,合法状态数较少(约 个),三重循环可接受。
复杂度:, 为合法状态数,可以过。