# 题目

## Description

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 S 1, S 2, S 3, S 4 ... S x, ... S n (1 ≤ x ≤ n ≤ 1,000,000, -32768 ≤ S x ≤ 32767). We define a function sum(i, j) = S i + ... + S j (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(i 1, j 1) + sum(i 2, j 2) + sum(i 3, j 3) + ... + sum(i m, j m) maximal (i x ≤ i y ≤ j x or i x ≤ j y ≤ j x 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(i x, j x)(1 ≤ x ≤ m) instead. ^_^

## Input

Each test case will begin with two integers m and n, followed by n integers S 1, S 2, S 3 ... S n.
Process to the end of file.
Output
Output the maximal summation described above in one line.

## Sample Input

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

6
8

# 题解

`dp[i][j]` 表示到以第 `i` 个数字结尾,分成 `j` 组的最大和

• 将数字加入到已选取的组中
`dp[i][j] = dp[i - 1][j] + a[i]`
• 将数字放到新的一组(上一组可能在之前的任意位置)
`dp[i][j] = max{dp[k][j - 1] + a[i]}`

(按照题目,最坏情况下甚至需要 `long long` )

```LL Max;
for(int j = 1;j <= m;j++) {
Max = -INF;
for(int i = j;i <= n;i++) {
dp[i] = max(dp[i - 1] + a[i],dp1[i - 1] + a[i]);
dp1[i - 1] = Max;
Max = max(dp[i],Max);
}
}
```

# 代码

```/*
By:OhYee
Github:OhYee
HomePage:http://www.oyohyee.com
Email:oyohyee@oyohyee.com

かしこいかわいい？
エリーチカ！

*/

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;

typedef int LL;

const LL INF = 0x7FFFFFFF / 2;

const int maxn = 1000005;
const int maxm = 1000005;

LL dp[maxm],dp1[maxm];
int a[maxn];
int v;

bool Do() {
int n,m;
if(scanf("%d%d",&m,&n) == EOF)
return false;

dp[0] = dp1[0] = 0;
for(int i = 1;i <= n;i++) {
scanf("%d",&a[i]);
dp[i] = 0;
dp1[i] = 0;
}

LL Max;

for(int j = 1;j <= m;j++) {
Max = -INF;
for(int i = j;i <= n;i++) {
dp[i] = max(dp[i - 1] + a[i],dp1[i - 1] + a[i]);
dp1[i - 1] = Max;
Max = max(dp[i],Max);
}
}

printf("%d\n",Max);
return true;
}

int main() {
while(Do());
return 0;
}
```