HDU Max Sum Plus Plus 最大m子段和

幻灯片 41

设d[i,j]为以j项结尾的i段和的最大值, 则需要枚举此段开头y和上一段结尾x, 即
d[i,j]=max{d[i-1,x] + a[y..j]}
每次需要枚举x<y<=j,决策量为O(n2), 状态为O(nm), 共O(n3m)
注意到如果a[j-1]也是本段的, 答案变成为d[i,j-1]+a[j], 因此方程优化为
d[i,j]=max{d[i,j-1]+a[j], d[i-1,x]+a[j]},x<j
优化后状态仍然是二维的,但决策减少为O(n), 总O(n2m)
可以继续优化. 注意到时间主要耗费在对x的枚举上, 计算max{d[i-1,x]}. 这个值…
我们把d的第一维称为”阶段”, 则本题是典型的多阶段决策问题
计算一个阶段时, 顺便记录本阶段最大值
只保留相邻两个阶段(滚动数组)
则时间降为O(nm), 空间降为O(n)

 

 

参考 黑书课件

 

 

1 //Accepted 1024 234MS 4956K 595 B C++ SuperBin
2  #include <stdio.h>
3 #include <string.h>
4  #define max(x,y) ((x)>(y)?(x):(y))
5  #define NIF 0xfffffff
6  #define NL 1000100
7
8  int d[NL], f[NL];
9  int a[NL];
10
11  int main()
12 {
13 int n, m;
14 int i, j;
15 while (scanf("%d%d", &m, &n) != EOF) {
16 for (i=1; i<=n; i++)
17 scanf("%d", &a[i]);
18 memset(d, 0, sizeof(d));
19
20 for (i=1; i<=n; i++) {
21 f[i] = -NIF;
22 d[i] = -NIF;
23 }
24 for (i=1; i<=n; i++) {
25 for (j=1; j<=m&&j<=i; j++) {
26 d[j] = max(d[j], f[j-1])+a[i];
27 f[j-1] = max(f[j-1], d[j-1]);
28 }
29 f[j-1] = max(f[j-1], d[j-1]);
30 }
31 printf("%d\n", f[m]);
32 }
33 return 0;
34 }
posted @ 2010-04-11 18:17  superbin  阅读(538)  评论(0编辑  收藏  举报