Beans
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2265 Accepted Submission(s): 1144
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 ?

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 6 11 0 7 5 13 9 78 4 81 6 22 4 1 40 9 34 16 10 11 22 0 33 39 6
Sample Output
242
Source
Recommend
//--------------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------------
吃豆豆
一个方格里一个值表示豆的质量,吃豆的规则是当你在(x,y)处吃了一个豆
那个这个豆的左边一格、右边一格、以及上一行、下一行的豆都不能吃。
问最多能吃到多少质量的豆
解题思路:
每一行计算最大质量,因为一个格子只能选择吃或者不吃,所以用用nsum[0]、nsum[1]分别表示到这个格子处吃、或者不吃的最大质量
用 cmax[0]、cmax[1] 表示前一格吃没吃豆子的最大质量
若在该点没有吃豆子 , 那显然可以从前状态可以推得到此最大值为 max(cmax[0],cmax[1]) , nsum[0] = max(cmax[0],cmax[1])
若在该点吃了豆子,那么根据规则,前一格必须没有吃 故 nsum[1] = cmax[0] + weight ;
用这两个式子去更新状态,到达行末是,max(cmax[0],cmax[1])就是这一行的最大质量。
算到这里,会发现,如果每一行的最大质量都算出来之后,我们就又得到一列数字,根据规则,吃了i行,那么i-1行与i+1行就不能吃
可否将这列数字又看成是一行,吃了第i个位置的大豆子,就不能再吃左边、右边的豆子
于是就可以根据刚才的更新规则再推一次,这次推完之后得到的就是题目所要求的最大质量了。
由于考虑到题目对于 m n 的限定是 1<=M*N<=200000
如果要开二维数组来存的话显然是不行的
所以就得到一个数据更新一次状态,就不用开数组了
#include<iostream>
#include<stdio.h>
using namespace std;
int main(){
int nsum[2] , pmax[2] , cmax[2] , rmax[2] , sum ;
int m , n , i , j , tmp ;
while( scanf( "%d%d" , &m , &n ) != EOF ){
memset(pmax,0,sizeof(pmax));
memset(rmax,0,sizeof(rmax));
for( i = 0 ; i < m ; ++i ){
memset(cmax,0,sizeof(cmax));
memset(nsum,0,sizeof(nsum));
for( j = 0 ; j < n ; ++j ){
scanf( "%d" , &tmp );
nsum[0] = cmax[1]>cmax[0]?cmax[1]:cmax[0];
nsum[1] = cmax[0]+tmp ;
cmax[0] = nsum[0];
cmax[1] = nsum[1];
}
sum = cmax[0]>cmax[1]?cmax[0]:cmax[1] ;
rmax[0] = pmax[1]>pmax[0]?pmax[1]:pmax[0];
rmax[1] = pmax[0]+sum;
pmax[0] = rmax[0];
pmax[1] = rmax[1];
}
printf( "%d\n" , pmax[0]>pmax[1]?pmax[0]:pmax[1] );
}
return 0;
}