标签:
经典的状态压缩DP题了。做了前面两题,就不感觉难了。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int stack[1<<10],cst; int dp[2][1<<10][1<<10]; int G[105],tot[1<<10]; char str[15]; int n,m; void Init(){ int alt=(1<<10); memset(tot,0,sizeof(tot)); for(int i=0;i<alt;i++){ int st=1; for(int j=0;j<10;j++){ st=1<<j; if(st&i) tot[i]++; } // cout<<tot[i]<<endl; } } void predo(){ cst=0; int alt=1<<m; int l1,l2,r1,r2; for(int i=0;i<alt;i++){ bool flag=true; for(int j=0;j<m;j++){ int st=1<<j; if(st&i){ l1=st<<1,l2=st<<2; r1=st>>1,r2=st>>2; if(l1&i){flag=false; break;} if(l2&i){flag=false; break;} if(r1&i){flag=false; break;} if(r2&i){flag=false; break;} } } if(flag) stack[cst++]=i; } // cout<<cst<<endl; } void slove(){ memset(dp,-1,sizeof(dp)); int cur=0,next=1; dp[cur][0][0]=0; for(int i=0;i<n;i++){ for(int j=0;j<cst;j++){ for(int k=0;k<cst;k++){ if(dp[cur][j][k]==-1) continue; for(int p=0;p<cst;p++){ // cout<<"YES"<<endl; if((stack[p]&G[i+1])!=stack[p]) continue; if(i>=1) if(stack[p]&stack[j]) continue; if(i>=2) if(stack[p]&stack[k]) continue; dp[next][p][j]=max(dp[next][p][j],dp[cur][j][k]+tot[stack[p]]); } } } memset(dp[cur],-1,sizeof(dp[cur])); swap(cur,next); } int ans=0; for(int i=0;i<cst;i++){ for(int j=0;j<cst;j++) ans=max(ans,dp[cur][i][j]); } printf("%d\n",ans); } int main(){ Init(); while(scanf("%d%d",&n,&m)!=EOF){ predo(); for(int i=1;i<=n;i++){ scanf("%s",str); G[i]=0; for(int j=0;j<m;j++){ G[i]<<=1; if(str[j]==‘P‘) G[i]|=1; } } slove(); } return 0; }
标签:
原文地址:http://www.cnblogs.com/jie-dcai/p/4381861.html