hdu2845

来源:互联网 发布:网络中级工程师报名费 编辑:程序博客网 时间:2024/05/18 09:15

Beans

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2493    Accepted Submission(s): 1238


Problem Description
Bean-eating is an interesting game, everyone owns an M*N matrix, which is filled with different qualities beans. Meantime, there is only one bean in any 1*1 grid. Now you want to eat the beans and collect the qualities, but everyone must obey by the following rules: if you eat the bean at the coordinate(x, y), you can’t eat the beans anyway at the coordinates listed (if exiting): (x, y-1), (x, y+1), and the both rows whose abscissas are x-1 and x+1.


Now, how much qualities can you eat and then get ?
 

Input
There are a few cases. In each case, there are two integer M (row number) and N (column number). The next M lines each contain N integers, representing the qualities of the beans. We can make sure that the quality of bean isn't beyond 1000, and 1<=M*N<=200000.
 

Output
For each case, you just output the MAX qualities you can eat and then get.
 

Sample Input
4 611 0 7 5 13 978 4 81 6 22 41 40 9 34 16 1011 22 0 33 39 6
 

Sample Output
242
 

把每一行单独出来,如果取了a[i],那么a[i-1]和a[i+1]都不可以取。求这样应该如何取数使所取的数的总和最大?

对于每个数,有取和不取两个状态:

dp[i][0] = max(dp[i-1][0], dp[i-1][1]);  //a[i] 不取
dp[i][1] = dp[i-1][0] + a[i];                  //a[i] 取

取 dp[i][0] 和 dp[i][1] 中的较大值,作为到 a[i] 这里做出的决策最多能得到的总和。


对每一行的处理得到的row[i]表示这一行所能取得的最大总和。由于某一行的某个数的取舍影响的是上下两行一整行的取舍,而不是上下两行某个具体位置的取舍,所以可以直接把第一次dp处理得到的每一行的最大总和合起来看做是一整行求最大总和,然后再进行一次同样的dp处理,得到整个矩阵的最大总和。

#include<iostream>  #include<cstring>  #include<algorithm>using namespace std;  int a[200005],dp[200005][2]; int row[200005];int main()  {  int m,n;  while(cin>>m>>n){int i,j,t=0,k;   dp[0][0] = dp[0][1] = 0; for(i=1;i<=m;++i)    {    for(j=1;j<=n;j++)    {  cin>>a[j];dp[j][0]=max(dp[j-1][0],dp[j-1][1]);//dp[j][0] 表示不取第j个能到的最大值dp[j][1]=dp[j-1][0]+a[j];//dp[j][1] 表示取第j个能到的最大值} row[i]=max(dp[n][0],dp[n][1]);} for (i = 1; i <= m; i++)        {            dp[i][0] = max(dp[i-1][0],dp[i-1][1]);            dp[i][1] = dp[i-1][0]+row[i];        }   cout<<max(dp[m][1],dp[m][0])<<endl;   }   return 0;    } 


0 0