炮兵阵地
N行M列网格,P可部署、H不可;炮兵横向左右
正文
/*
原题:T1595 「一本通 5.4 练习 2」炮兵阵地 (NOI 2001)
题意:N 行 M 列(M≤10)网格,P 可部署、H 不可;炮兵横向左右各 2、纵向上下各 2 受击;求最多部署数。
思路:行状压。单行合法状态 s:只落在 P 上,且任意两个 1 距离 ≥3(s&(s<<1)==0 且 s&(s<<2)==0)。
用 dp[本行状态][上一行状态] 记录前 i 行最大炮兵数;新行 u 需与上一行 s、上两行 t 均不共列:u&(s|t)==0。
复杂度:时间 O(N·S³),空间 O(S²),S 为合法单行状态数(M=10 时 S≤60)。
易错点:1) 攻击范围是 2 格(非相邻),故需检查错位 1 与 错位 2;
2) 需同时与“上一行”和“上两行”无冲突;3) 山地 H 上不可部署。
*/
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int N,M;
if(!(cin>>N>>M)) return 0;
vector<int> plain(N,0);
for(int i=0;i<N;i++){
string s; cin>>s;
for(int j=0;j<M;j++) if(s[j]=='P') plain[i]|=(1<<j);
}
// 对每一行,找出所有合法状态(落在 P 上且两两相距 ≥3)
vector<vector<int>> rowSt(N), rowCnt(N);
for(int i=0;i<N;i++){
for(int s=0;s<(1<<M);s++){
if((s&plain[i])!=s) continue;
if((s&(s<<1))!=0) continue;
if((s&(s<<2))!=0) continue;
rowSt[i].push_back(s);
rowCnt[i].push_back(__builtin_popcount(s));
}
}
int S0=rowSt[0].size();
// dp[b][c]:处理完“当前行”后,当前行状态 b、上一行状态掩码 c(c=0 表示无)的最大炮兵数
vector<vector<int>> dp(S0,vector<int>(1,-1));
for(int b=0;b<S0;b++) dp[b][0]=rowCnt[0][b];
vector<int> ppMasks={0}; // 上两行的状态掩码列表,初始为“无”
for(int i=1;i<N;i++){
int Si=rowSt[i].size();
int Sp=rowSt[i-1].size();
vector<vector<int>> nd(Si,vector<int>(Sp,-1));
for(int a=0;a<Si;a++){
int ma=rowSt[i][a];
int ca=rowCnt[i][a];
for(int b=0;b<Sp;b++){
int mb=rowSt[i-1][b];
if((ma&mb)!=0) continue;
for(int c=0;c<(int)ppMasks.size();c++){
if(dp[b][c]<0) continue;
int mc=ppMasks[c];
if((ma&mc)!=0) continue;
if(nd[a][b]<dp[b][c]+ca) nd[a][b]=dp[b][c]+ca;
}
}
}
dp=move(nd);
ppMasks=rowSt[i-1]; // 下一轮的“上两行”即当前的上行
}
int ans=0;
for(int b=0;b<(int)dp.size();b++)
for(int c=0;c<(int)dp[b].size();c++)
if(dp[b][c]>ans) ans=dp[b][c];
cout<<ans<<"\n";
return 0;
}
一本通·提高篇的其它内容
- 活动安排
- 种树
- 喷水装置
- 加工生产调度
- 智力大冲浪
- 数列极差
- 数列分段
- 线段
- 家庭作业
- 钓鱼
- 糖果传递
- 愤怒的牛
- Best Cow Fences
- 曲线
- 数列分段 II
- 扩散
- 灯泡
- 传送带
- 数的划分
- 生日蛋糕
- 小木棍
- Addition Chains
- 埃及分数
- 平板涂色
- 质数方阵
- 靶形数独
- 电路维修
- 魔板
- Knight Moves
- 棋盘游戏
- Keyboarding
- 移动玩具
- 山峰和山谷
- Oulipo
- 图书管理
- Power Strings
- Seekthe Name, Seek the Fame
- Friends
- A Horrible Poem
- Beads
- Antisymmetry
- 门票
- 收集雪花
- 剪花布条
- Power Strings
- Radio Transmission
- OKR-Periods of Words
- 似乎在梦中见过的样子
- Censoring
- Phone List
- The XOR Largest Pair
- Nikitosh 和异或
- Immediate Decodability
- L 语言
- Secret Message 秘密信息
- 背单词
- The Xor-longest Path
- Keywords Search
- 玄武密码
- Censoring