题解:nState为状态数,state数组为可能的状态
代码:
#include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <vector> #include <cstdio> #include <string> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int INF=0x3f3f3f3f; typedef long long ll; typedef unsigned long long ull; #define fi first #define se second #define prN printf(" ") #define SI(N) scanf("%d",&(N)) #define SII(N,M) scanf("%d%d",&(N),&(M)) #define SIII(N,M,K) scanf("%d%d%d",&(N),&(M),&(K)) #define cle(a,val) memset(a,(val),sizeof(a)) #define rep(i,b) for(int i=0;i<(b);i++) #define Rep(i,a,b) for(int i=(a);i<=(b);i++) int n,m,dp[105][80][80]; int row[105]; int nState,state[80],num[80]; void init() { int k=1<<m; nState=0; rep(i,k) { if ((i&(i<<1))==0&&(i&(i<<2))==0) { state[nState]=i; num[nState]=0; int j=i; while(j) { num[nState]+=j%2; j/=2; } nState++; } } } int main() { #ifndef ONLINE_JUDGE freopen("C:\Users\Zmy\Desktop\in.txt","r",stdin); // freopen("C:\Users\Zmy\Desktop\out.txt","w",stdout); #endif // ONLINE_JUDGE char str[20]= {0}; while(cin>>n>>m) { init(); rep(i,n) { row[i]=0; scanf("%s",str); rep(j,m) { if (str[j]=='P') { row[i]+=1<<j; } } } cle(dp,0); rep(j,nState) { if ((state[j]&row[0])!=state[j]) { continue; } rep(k,nState) { dp[0][j][k]=num[j]; } } if (n>1) rep(j,nState) { if ((state[j]&row[1])!=state[j]) { continue; } rep(k,nState)//这的k代表的是上上个 { if ((state[j]&state[k])==0) { dp[1][j][k]=dp[0][k][0] + num[j];/**< 这是啥意思?? */ } } } Rep(i,2,n-1) { rep(j,nState) { if ((state[j]&row[i])!=state[j]) { continue; } rep(k,nState)//这的k代表的是上上个 { if ( state[j] & state[k] ) continue; for (int h = 0; h < nState; h++)/**< i是这个,j是上1,k是上2,h是上3 */ { if ( state[j] & state[h] ) continue; if ( dp[i-1][k][h] > dp[i][j][k] ) dp[i][j][k] = dp[i-1][k][h]; } dp[i][j][k] += num[j]; } } } int maxa = 0; for (int j = 0; j < nState; j++) { for (int k = 0; k < nState; k++) if (maxa < dp[n-1][j][k]) maxa = dp[n-1][j][k]; } printf("%d ", maxa); } return 0; }