Problem: http://acm.hdu.edu.cn/showproblem.php?pid=2845

1 /* 2 对于任意一行的每个数,只有两种可能,取或不取,所以它的状态只能是它左边的数没取而取它,或者左边的取了不取它, 再或者左边的没取,它也不取。 3 首先对每行求最大的序列和,记录起来。最后构造出了一个从上到下的序列,然后对这个序列再求最大序列和即是答案。 4 5 156MS 252K 6 */ 7 8 #include <iostream> 9 #include <cstdio> 10 #include <cstring> 11 #include <algorithm> 12 #define SIZE 200005 13 14 using namespace std; 15 16 int dp[SIZE][2]; 17 int Maxrow[SIZE]; 18 int M,N; 19 20 int main() 21 { 22 while(~scanf("%d%d",&M,&N)) 23 { 24 for(int i=1; i<=M; i++) 25 { 26 for(int j=1; j<=N; j++) 27 { 28 int temp; 29 scanf("%d",&temp); 30 if(j <= 1) 31 dp[j][1] = temp; 32 else 33 { 34 dp[j][0] = max(dp[j-1][0],dp[j-1][1]); 35 dp[j][1] = dp[j-1][0]+temp; 36 } 37 } 38 Maxrow[i] = max(dp[N][0],dp[N][1]); 39 } 40 dp[1][0] = 0; 41 dp[1][1] = Maxrow[1]; 42 for(int i=2; i<=M; i++) 43 { 44 dp[i][0] = max(dp[i-1][0],dp[i-1][1]); 45 dp[i][1] = dp[i-1][0]+Maxrow[i]; 46 } 47 int ans = max(dp[M][0],dp[M][1]); 48 printf("%d\n",ans); 49 } 50 return 0; 51 }