把数组竖起来,从上往下走。
如果当前位置是竖着乘的,那么第一个点标记为1.否则标记为0.
样例最终的状态为:
0 0 1
0 1 0
1 0 0
0 0 0
#include<iostream> #include<cmath> #include<algorithm> #include<stdio.h> #include<string.h> #define max(a,b) ((a)>(b)?(a):(b)) using namespace std; int maps[1010][11]; int dp[1010][11]; int pan(int x,int y) { int i; for(i=0;i<3;i++) { int tt=(1<<i); if((x&tt)&&(y&tt))return 0; } return 1; } int add(int x,int y,int z) { int ans=0; int ss[4]; int i; for(i=0;i<3;i++) { if(x&(1<<i))ss[i+1]=1; else ss[i+1]=0; } for(i=0;i<3;i++) { if(y&(1<<i)) { ans+=maps[z-1][i+1]*maps[z][i+1]; ss[i+1]=1; } } int t1,t2; t1=t2=0; if(ss[1]==0&&ss[2]==0)t1=maps[z][1]*maps[z][2]; if(ss[2]==0&&ss[3]==0)t2=maps[z][2]*maps[z][3]; ans+=max(t1,t2); return ans; } int main() { int i,j,k,n; int cas=0; while(~scanf("%d",&n)&n) { cas++; memset(maps,0,sizeof(maps)); memset(dp,0,sizeof(dp)); for(i=1;i<=3;i++) { for(j=1;j<=n;j++) { scanf("%d",&maps[j][i]); } } for(i=1;i<=n;i++) { for(j=0;j<(1<<3);j++) { for(k=0;k<(1<<3);k++) { if(pan(j,k)) { dp[i][j]=max(dp[i-1][k]+add(j,k,i),dp[i][j]); } } } } int maxx=-1; for(j=0;j<(1<<3);j++) { maxx=max(maxx,dp[n][j]); } printf("Case %d: ",cas); cout<<maxx<<endl; } }