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;
}
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;
}
相关文章推荐
- 求整数序列最大面积
- 最大子序列问题
- 求最大连续子序列的和
- 输入n个元素组成的序列S,你需要找出一个乘积最大的连续子序列。如果这个最大的乘积不是正数,应输出0(表示无解)。1<=18,-10<=Si<=10
- 最大子数组之和、最大子数组之积、最长递增子序列求法
- 采用递归求数组里面求最大子序列的算法(手绘图解)
- 最大连续子序列(dp水题)
- HDU 1231 最大连续子序列 (线性dp)
- 最大子序列和 最大子矩阵和
- hdu 1231 最大连续子序列
- 线性序列中同时求出最大值和最小值
- 九度OJ 1077:最大序列和 (DP)
- 求整形数组中最大递增序列的长度
- 最大连续子序列
- 最大连续子序列的和
- 求最大子序列之和的四种方法
- 求最大子序列的和
- 求最大子序列和
- [转] 最大子序列和问题
- 【codevs 1906】最长递增子序列问题(dp+最大流)