您的位置:首页 > 其它

Max Sum Plus Plus m段连续子序列最大和

2017-08-28 18:03 106 查看
Now I think you have got an AC in Ignatius.L's "Max Sum" problem. To be a brave ACMer, we always challenge ourselves to more difficult problems. Now you are faced with a more difficult problem.

Given a consecutive number sequence S1, S2, S3, S4 ... Sx, ... Sn (1 ≤ x ≤ n ≤ 1,000,000, -32768 ≤ Sx ≤ 32767). We define
a function sum(i, j) = Si + ... + Sj (1 ≤ i ≤ j ≤ n).

Now given an integer m (m > 0), your task is to find m pairs of i and j which make sum(i1, j1) + sum(i2, j2) + sum(i3, j3) + ... + sum(im,
jm) maximal (ix ≤ iy ≤ jx or ix ≤ jy ≤ jx is not allowed).

But I`m lazy, I don't want to write a special-judge module, so you don't have to output m pairs of i and j, just output the maximal summation of sum(ix, jx)(1 ≤ x ≤ m) instead. ^_^

 

[align=left]Input[/align]
Each test case will begin with two integers m and n, followed by n integers S1, S2, S3 ... Sn.

Process to the end of file.

 

[align=left]Output[/align]
Output the maximal summation described above in one line.

 

[align=left]Sample Input[/align]

1 3 1 2 3
2 6 -1 4 -2 3 -2 3

 

[align=left]Sample Output[/align]
6
8

算是最大连续子序列和的加强版吧

状态:dp[i][j]表示前j个元素组成i组子序列和的最大值

状态转移:dp[i][j] = max(dp[i][j-1], max(dp[i-1][k])) + a[j] ,注意这里 i-1 <= k >= j-1

但是 j <= n <= 10000000,而且m的范围不知道,所以很有可能超内存...

看了网上的做法,说用什么滚动数组?记录前一组的最大值,所以是不断更新的

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;
const int N = 1e6 + 3;

int dp
, a
, pre
; //pre数组记录前一段和的最大值

int main()
{
int m, n;
while(~scanf("%d%d", &m, &n))
{
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]);
memset(pre, 0, sizeof(pre));
dp[0] = 0;
int p;
for(int i = 1; i <= m; i++)
{
p = -1e9;
for(int j = i; j <= n; j++) //这里j一定要从i开始,因为每一组的元素数量肯定至少是1...
{
dp[j] = max(dp[j-1], pre[j-1]) + a[j];
pre[j-1] = p; //记录下来,为i+1组使用,使用后更新,为下一组使用
p = max(p, dp[j]);
}
}
printf("%d\n", p);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: