算法提高之炮兵阵地
-
核心思想:状态压缩dp + 滚动数组优化
- 考虑前两层状态 用f[i,j,k]表示前i层,第i层状态j,第i-1层状态k的方案
- 同“玉米田” g存图1是不能放的位置
- **滚动数组优化:**所有第一维n或者n+1 &1
-
#include <iostream>#include <vector>using namespace std;const int N = 110, M = 1 << 10;int n, m;int g[N], cnt[M];int f[2][M][M];vector<int> state;vector<int> head[M];bool check(int st) //左右各两格不能相同{return !(st & st >> 1 || st & st >>2);}int count(int st) //数1的数量{int res=0;while(st) res+= st&1 , st>>=1;return res;}int main(){cin>>n>>m;for(int i=1,j=0;i<=n;i++,j=0)for(char c;j<m&&cin>>c;j++)g[i] += (c=='H') << j; //1为不能放的地方for(int st=0;st<1<<m;st++) //找合法状态if(check(st))state.push_back(st),cnt[st] = count(st);for(int cur_st:state) //找组合状态for(int pre_st:state)if(!(cur_st & pre_st))head[cur_st].push_back(pre_st);for(int i=1;i<=n;i++)for(int st:state)if(!(g[i] & st)) //合法方案for(int p1:head[st])for(int p2:head[p1])if(!(st & p2))f[i&1][st][p1] = max(f[i&1][st][p1] , f[i-1&1][p1][p2] + cnt[st]);int res=0;for(int st:state)for(int pre:head[st])res = max(res,f[n&1][st][pre]);cout<<res<<endl;}