hdu 2845

题目概述

有一矩阵R行C列的矩阵,每个位置有一个数a,在矩阵中可任意取数,但所取位置的左右一格和上下一行所有位置不可再取,给出矩阵,求所取数最大和

时限

1000ms/2000ms

输入

每组数据第一行正整数R,C,其后R行,每行C个整数,输入到EOF为止

限制

a<=1000;1<=R*C<=200000

输出

每行一个数,所求最大和

样例输入

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

样例输出

242

讨论

dp,看似是矩阵移动,然而可移动的范围太广了,进一步分析取数特征可发现,每行内不能连续取数,也不能在连续的行中取数,便转化为求每行的最大不连续子序列和,作为每行的最大值,然后对每行的最大值再求最大不连续子序列和,即是结果
由于这个题求最大值不带条件也没上限,因而可采取线性级方法,(带上限的话只能用平方级的),这样便不会超时
额不太理解为何额直接取每行的最大值竟然比从每行中找出最大值还要慢

题解状态

405MS,1736K,629 B,C++

题解代码

#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 200003
#define memset0(a) memset(a,0,sizeof(a))

int dp1[MAXN], dp2[MAXN];//对行内部和每行的dp辅助数组
int fun(int R, int C)
{
    for (int p = 0; p < R; p++) {
        for (int i = 0; i < C; i++) {
            int a;
            scanf("%d", &a);//input
            dp1[i] = max(dp1[i - 1], dp1[i - 2] + a);//转移方程 要么不拿照抄上一个dp值 要么隔一个dp值加上自身值
        }
        dp2[p] = max(dp2[p - 1], dp2[p - 2] + dp1[C - 1]);//转移方程 对行之间同理 如果最后dp1[C-1]改成*max_element函数反而能快100ms
    }
    return dp2[R - 1];
}
int main(void)
{
    //freopen("vs_cin.txt", "r", stdin);
    //freopen("vs_cout.txt", "w", stdout);

    int R, C;
    while (~scanf("%d%d", &R, &C))//input
        printf("%d\n", fun(R, C));//output
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值