分析:先枚举出来所有的合法状态(当N=10的时候合法状态最多也就60种),用当前状态匹配上一行和上上一行的状态去匹配,看是否可以.....复杂度100*60*60*60,也可以接受。
代码如下:
=========================================================================================================================
#include<stdio.h> #include<algorithm> #include<string.h> using namespace std; const int MAXN = 107; const int MAXM = 67; int dp[MAXN][MAXM][MAXM]; int HaveOne(int x, int N) { int s[MAXN]={0}, sum=0; for(int i=N-1; i>=0; i--) { s[i] = (x&1); x >>= 1; if(s[i] && (s[i+1] || s[i+2])) return -1; if(s[i])sum++; } return sum; } int main() { int M, N; while(scanf("%d%d", &M, &N) != EOF) { char s[MAXN]; int data[MAXN]={0}, nOne[MAXM], bit[MAXM], cnt=0; for(int i=0; i<(1<<N); i++) { nOne[cnt] = HaveOne(i, N); if(nOne[cnt] != -1) { bit[cnt++] = i; } } for(int i=2; i<=M+1; i++) { scanf("%s", s); for(int j=0; j<N; j++) data[i] = data[i]*2 + (s[j]==‘P‘ ? 0 : 1); } memset(dp, false, sizeof(dp)); int ans=0; for(int t=2; t<=M+1; t++) { for(int i=0; i<cnt; i++)if( !(bit[i] & data[t]) ) for(int j=0; j<cnt; j++)if( !(bit[j] & data[t-1]) ) for(int k=0; k<cnt; k++)if( !(bit[k] & data[t-2]) ) { if(!(bit[i] & bit[j]) && !(bit[j] & bit[k]) && !(bit[i] & bit[k])) { dp[t][i][j] = max(dp[t][i][j], dp[t-1][j][k]+nOne[i]); ans = max(ans, dp[t][i][j]); } } } printf("%d\n", ans); } return 0; }
时间: 2024-11-03 15:06:03