HDU2845 Beans

37 篇文章 0 订阅

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 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

题意:

题意是比较难理解的,思路并不难,主要是理解是如何吃的豆豆。比如81这个数,他的左边和右边都是不可以选择的,上面一列和下面一列也是都不可以选择的。自己一开始没有理解题意。第二次的选择也是要遵循这个原则的,这样算下来能选择的就很少了。

思想就是dp

把每一行单独出来,如果取了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] 这里做出的决策最多能得到的总和。

先的到每一行的最大值,再得到每一列的最大值

状态转移方程: dp1[j]=max(dp1[j-1],dp1[j-2]+s[i][j]);

                           dp2[i]=max(dp2[i-1],dp2[i-2]+dp1[m+1]);

dp1是来记录每行的最大不连续子序列,然后把dp1压缩成一个元素来看待。

然后把两个球最大上升子序列组合起来求解就可以了。

时间复杂度n*n;

代码如下

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m;
int s[10005][10005];
int dp1[200005],dp2[200005];
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=2;i<n+2;i++)
        {
            for(int j=2;j<m+2;j++)
            {
                scanf("%d",&s[i][j]);
            }
        }
        int maxn=-1;
        for(int i=2;i<n+2;i++)
        {
            for(int j=2;j<m+2;j++)
            {
                dp1[j]=max(dp1[j-1],dp1[j-2]+s[i][j]);
            }
            dp2[i]=max(dp2[i-1],dp2[i-2]+dp1[m+1]);
        }
        cout << dp2[n+1] << endl;
    }
    return 0;
}

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值