poj 1185 炮兵阵地
http://poj.org/problem?id=1185
dp[i][j][k]表示第i行状态为k,第i-1行为j;状态转移方程dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k]+c[k]);
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define maxn 1000 5 using namespace std; 6 7 int dp[105][105][105]; 8 int n,m; 9 char str[maxn]; 10 int a[maxn],st[1<<11],c[maxn]; 11 int num,cnt; 12 13 void inti() 14 { 15 for(int i=0; i<(1<<m); i++) 16 { 17 if((i&(i<<1))||(i&(i<<2))) continue; 18 st[num]=i; 19 int tem=i,m1=0; 20 while(tem) 21 { 22 m1++; 23 tem&=tem-1; 24 } 25 c[num++]=m1; 26 } 27 } 28 29 int main() 30 { 31 while(scanf("%d%d",&n,&m)!=EOF) 32 { 33 memset(dp,0,sizeof(dp)); 34 memset(c,0,sizeof(c)); 35 memset(st,0,sizeof(st)); 36 memset(a,0,sizeof(a)); 37 num=0; 38 inti(); 39 for(int i=1; i<=n; i++) 40 { 41 scanf("%s",str); 42 for(int j=0; j<m; j++) 43 { 44 if(str[j]=='H') 45 { 46 a[i]+=(1<<j); 47 } 48 } 49 } 50 cnt=0; 51 for(int i=0; i<num; i++) 52 { 53 if(a[1]&st[i]) continue; 54 dp[1][0][i]=c[i]; 55 if(cnt<dp[1][0][i]) 56 cnt=dp[1][0][i]; 57 } 58 for(int i=2; i<=n; i++) 59 { 60 for(int j=0; j<num; j++) 61 { 62 for(int k=0; k<num; k++) 63 { 64 if((st[j]&st[k])||(a[i]&st[k])||(a[i-1]&st[j]))continue; 65 for(int x=0; x<num; x++) 66 { 67 if((st[k]&st[x])||(st[j]&st[x])||(a[i-2]&st[x])||!dp[i-1][x][j]) continue; 68 dp[i][j][k]=max(dp[i][j][k],dp[i-1][x][j]+c[k]); 69 cnt=max(cnt,dp[i][j][k]); 70 } 71 } 72 } 73 } 74 printf("%d\n",cnt); 75 } 76 return 0; 77 }