POJ-1185 炮兵陣地
阿新 • • 發佈:2018-12-12
思路:狀態壓縮DP,對每行的狀態進行列舉,由於一個炮兵影響相鄰兩行,因此用 dp[i][j][k]來儲存 第i行的狀態為j,第 i-1行狀態為k時的最大個數。
Code :
#include<iostream> #include<cstring> using namespace std; const int MAX_N=105; const int MAX_M=75; int n,m; int d[MAX_N],p[MAX_M],s[MAX_M]; int dp[MAX_N][MAX_M][MAX_M]; int Find(int x){ int res=0; while(x){ if(x&1) ++res; x>>=1; } return res; } bool judge1(int x){ return (x&(x<<1))||(x&(x<<2)); } bool judge2(int a,int b){ return a&b; } int main() { ios::sync_with_stdio(false); while(cin>>n>>m){ memset(d,0,sizeof(d)); memset(dp,0,sizeof(dp)); string str; for(int i=1;i<=n;++i) { cin>>str; for(int j=0;j<m;++j) if(str[j]=='H') d[i]+=(1<<j); } int ss=0,mm=(1<<m)-1; for(int i=0;i<=mm;++i) if(!judge1(i)){ s[ss]=Find(i); p[ss++]=i; } for(int i=0;i<ss;++i) if(!judge2(d[1],p[i])) dp[1][i][0]=s[i]; for(int i=0;i<ss;++i) if(!judge2(d[2],p[i])){ for(int j=0;j<ss;++j) if(!judge2(d[1],p[j])&&!judge2(p[i],p[j])){ dp[2][i][j]=max(dp[2][i][j],dp[1][j][0]+s[i]); } } for(int i=3;i<=n;++i) for(int j=0;j<ss;++j) if(!judge2(d[i],p[j])){ for(int t1=0;t1<ss;++t1) if(!judge2(p[j],p[t1])&&!judge2(d[i-1],p[t1])){ for(int t2=0;t2<ss;++t2) if(!judge2(p[j],p[t2])&&!judge2(p[t1],p[t2])&&!judge2(d[i-2],p[t2])){ dp[i][j][t1]=max(dp[i][j][t1],dp[i-1][t1][t2]+s[j]); } } } int ans=0; for(int i=0;i<ss;++i) for(int j=0;j<ss;++j) ans=max(ans,dp[n][i][j]); cout<<ans<<endl; } return 0; }