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 ≤ iy ≤ 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. ^_^
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 ≤ iy ≤ 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. ^_^
InputEach test case will begin with two integers m and n, followed by n integers S 1, S2, S 3 ... S n.
Process to the end of file.
OutputOutput the maximal summation described above in one line.
Sample Input
1 3 1 2 3 2 6 -1 4 -2 3 -2 3
Sample Output
6 8
Hint
Huge input, scanf and dynamic programming is recommended.
最近这段时间来复习基础DP 必须强化一下DP了
什么DP都不会 我好绝望啊
这个题目 我是看题解写的 ,慢慢来 。
总有一天我能够自己写DP的。
题意是一个长度为n的数组 分成不想交的m个字段
求出子段和最大值的问题
这题很明显的是一个DP
我写的代码是参考 kuangbin 大神的
解析很详细。
这个代码优化非常非常的强
for (int i=1 ;i<=m ;i++ ) 枚举子序列短,
for (int j=i ;j<=n ;j++) 因为对应的是第i个字段,所以最少前面要有 i 个元素
所以从 i 开 头 枚举
用 maxn 记录此时的
每次进行枚举一个字段时候 都要讲maxn进行初始化
maxn 记录的是最大值 ,num[ j - 1 ] 记录上一次的最大值
maxn = max(dp[j], maxn); 这个就是用来比较相加后 值变大了 还是变小了。
以上就是我的理解 ! DP需要顿悟啊。
1 #include <cstdio> 2 #include <iostream> 3 #include <set> 4 #include <string> 5 #include <cstring> 6 #include <cstdio> 7 #include <algorithm> 8 #include <cmath> 9 #include <queue> 10 #include <vector> 11 using namespace std; 12 13 const int maxn = 1e6 + 10; 14 const int inf = 1e9 + 7; 15 16 int dp[maxn], num[maxn], a[maxn]; 17 int n, m; 18 19 int main() { 20 while(scanf("%d%d", &m, &n) != EOF) { 21 for (int i = 1 ; i <= n ; i++ ) { 22 scanf("%d", &a[i]); 23 dp[i] = 0; 24 num[i] = 0; 25 } 26 dp[0] = 0; 27 num[0] = 0; 28 int maxn; 29 for (int i = 1 ; i <= m ; i++ ) { 30 maxn = -inf; 31 for (int j = i ; j <= n ; j++) { 32 dp[j] = max(dp[j - 1], num[j - 1]) + a[j]; 33 num[j - 1] = maxn; 34 maxn = max(dp[j], maxn); 35 } 36 } 37 printf("%d ", maxn); 38 } 39 return 0; 40 }