题意
- 给定N*M的地图,包含山地和平地,山地不能布置炮兵
- 炮兵会攻击自己上下两格,左右两格的位置,请问在炮兵相互不打架的情况下,地图上最多放置多少炮兵
思路
- 仍旧按行考虑,预处理行内可行状态
- 枚举每行可能性,和前两行状态有关,所以是一个三维的dp
表示第i行状态j,i-1行状态为k
&preview=true)
代码
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
/**
* dp[i][j][k]表示第i行状态j,i-1行状态为k
* dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][p]+num[j])
* H=1,P=0;
*/
int N,M;
int mp[120],dp[120][100][100];
vector<int>st;
vector<int>num;
int calc(int x){
int ans=0;
while(x){
ans+=x&1;
x>>=1;
}
return ans;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin >> N >> M;
//build the map
for(int i=1;i<=N;i++){
for(int j=1;j<=M;j++){
char c;
cin >> c;
if(c=='H') mp[i]|=(1<<(j-1));
}
}
//find all condition
for(int i=0;i<(1<<M)-1;i++){
if(i&(i<<1)||i&(i<<2)) continue;
st.push_back(i);
num.push_back(calc(i));
}
//dp
for(int i=1;i<=N;i++){
for(int j=0;j<st.size();j++){
if(st[j]&mp[i])continue;
for(int k=0;k<st.size();k++){
if(st[j]&st[k])continue;
for(int p=0;p<st.size();p++){
if(st[p]&st[k]||st[p]&st[j]) continue;
dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][p]+num[j]);
}
}
}
}
int ans=0;
for(int i=0;i<st.size();i++){
for(int j=0;j<st.size();j++){
ans=max(ans,dp[N][i][j]);
}
}
cout << ans << endl;
return 0;
}