NYOJ 742 —— 最大m段和 【区间DP】

经典区间DP:最大m段和

“最大连续和问题”是最大m段和问题的一个特例,其实是当m=1的一种特殊情况。

OJ题目:http://acm.nyist.net/JudgeOnline/problem.php?pid=742

 
 
#include <iostream>
#include <cstdio>
#define INF 0x3f3f3f3f
using namespace std;

const int MAXN = 1000000 + 5;

typedef long long LL;

int a[MAXN];
LL dp[MAXN];
LL maxn[MAXN];

/*
    dp[i][j] = max(dp[i][j-1]+a[j], max(dp[i-1][k])+a[j])    (i-1 <= k < j)
  下面的代码进行了两个很重要的优化:1.滚动数组,空间减少一维 2. 通过动态维护上一行中[i-1,j)的最大值,省去k的一重循环
*/ int main () { int T, m, n; scanf("%d", &T); while(T--) { scanf("%d%d", &m, &n); for(int i=1; i<=n; i++) { scanf("%d", &a[i]); } for(int j=0; j<=n; j++) maxn[j] = dp[j] = 0; LL t; for(int i=1; i<=m; i++) { t = -INF; for(int j=0; j<=n; j++) {
          // 把j个数分成比j还多的段,这是不合法的
if(i>j) dp[j] = -INF; else { dp[j] = max(dp[j-1]+a[j], maxn[j-1]+a[j]); // maxn[j-1]已经被使用完毕,所以可以赋值了 maxn[j-1] = t; // t保存第i行、i~j列的最大dp值, // 但是t不能马上赋值给maxn[j],因为下一次循环到j+1时,要用到原来的maxn[j] t = max(t, dp[j]); } } } printf("%lld\n", t); } return 0; }

 

参考:

http://blog.csdn.net/liufeng_king/article/details/8632430

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值