HDU 2845 Beans

#include<iostream> #include<algorithm> using namespace std; #define MAX(a,b) (a)>(b)?(a):(b) #define M 2001 int Count[M][M]; //4090888 2011-06-25 21:03:05 Accepted 2845 156MS 7864K 734 B C++ ashione /* 分别对横竖求最大非连续和,对横求的是一个列的最大和, 对竖求的是每一列的最大和然后最大和 状态转移方程 count[i][j]=MAX(Count[i][j-2],Count[i][j-3])+a[i][j]; 想一下为什么不是 count[i][j]=MAX(Count[i][k])+a[i][j] (k=1...i-2); 因为貌似全部数字都是正数,所以恰好符合j-2,j-3的最大值是j的前驱。 那么,同理可得这一列的最大和就是 MAX(count[i][m-1],count[i][m-2])也就是最后两个, 那么现在设dp[i]= (一列的最大和) 所以最大的不连续和就是 MAX ( dp[i]=MAX(dp[j])+dp[i] (j=1...i-2) ) ,(i=1...n); 又由上面得 MAX ( dp[i]=MAX(dp[i-2],dp[i-3)+dp[i] ) ,(i=n-1,n); */ int main(){ int n,m,a; while(scanf("%d %d",&n,&m)!=EOF){ int i,j,dp[M]; for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ scanf("%d",&a); int max=0; if(j>2) max=MAX(max,Count[i][j-2]); if(j>3) max=MAX(max,Count[i][j-3]); Count[i][j]=max+a; } dp[i]=MAX(Count[i][m],Count[i][m-1]); } for(i=1;i<=n;i++){ int max=0; if(i>2) max=MAX(max,dp[i-2]); if(i>3) max=MAX(max,dp[i-3]); dp[i]+=max; } int p=MAX(dp[n],dp[n-1]); cout<<p<<endl; } return 0; }

你可能感兴趣的:(HDU 2845 Beans)