P2704 [NOI2001] 炮兵阵地

/*
状态dp
n*m的图中 每次选一点 覆盖 。 . 。。+ 。 。 。 。 +不能被。覆盖 问最多能放置几个 m<=10 选/不选 ->状压 dp[i][P][k][L]=max(dp[i][P][k][L],dp[i-1][k][L][F]+sum(P)) 第一维不能滚掉 因为 不是紧接着更新的 可能 被这一层已经更新 所以%2 -> 0-n-1 128MB 1e8/8/1024/1024 */ /* */ #include<cstdio> #include<iostream> #include<algorithm> #include<cmath> #include<string.h> #include<queue> #include<vector> #include<bits/stdc++.h> #define ll long long #define ddd printf("-----------------------\n"); using namespace std; const int maxn=1e1 +10; const int mod=998244353; const int inf=0x3f3f3f3f; int n,m,dp[3][(1<<10)+10][(1<<10)+10],sum[(1<<10)+10],a[110],ans; int getsum(int k) { int res=0; while(k) { if(k&1) res++; k>>=1; } return res; } int main() { ios::sync_with_stdio(false); cin>>n>>m; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ char tmp;cin>>tmp; a[i]<<=1,a[i]+=(tmp=='H'); } } //for(int i=1;i<=n;i++) cout<<a[i]<<endl; for(int i=0;i<(1<<m);i++) sum[i]=getsum(i); for(int S=0;S<(1<<m);S++){ if((a[0]&S || S&(S<<2) || S&(S<<1))==0) dp[0][S][0]=getsum(S); } for(int S=0;S<(1<<m);S++){ for(int L=0;L<(1<<m);L++){ if((L&a[0] || S&a[1] || S&L || L&(L<<1) || L&(L<<2) || S&(S<<1) || S&(S<<2) )==0 ) dp[1][S][L]=sum[S]+sum[L];//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! } } for(int i=2;i<n;i++) { for(int S=0;S<(1<<m);S++) { if(S&(S<<1) || S&(S<<2) || S&a[i]) continue; for(int L=0;L<(1<<m);L++) { if(L&(L<<1) || L&(L<<2) || L&a[i-1] || L&S ) continue; for(int FL=0;FL<(1<<m);FL++) { if(FL&(FL<<1) || FL&(FL<<2) || FL&a[i-2] || FL&S || FL&L) continue; dp[i%2][S][L]=max(dp[i%2][S][L],dp[(i-1)%2][L][FL]+sum[S]); } } } } for(int L=0;L<(1<<m);L++)//!!!!!!!!!!!!!!!!!!!!!!!!!! for(int S=0;S<(1<<m);S++) ans=max(ans,dp[(n-1)%2][S][L]); cout<<ans<<'\n'; return 0; }

 

posted @ 2023-11-15 04:05  JMXZ  阅读(4)  评论(0)    收藏  举报