/*超时。题意:输出m个子序列和的最大值思路:动态规划 + 滑动数组d[m][j] = max(d[m][j - 1] + e[j], max(d[m - 1][k] + e[j]) | k ∈ [m -1, j)).表示前j个序列分割成m组,最大序列和因为状态方程中只用到d[m]和d[m - 1]两个状态,所以只需要一个二维数组即可。优化:至于max(d[m - 1][k] + e[j])过程,可以直接在d[0][j]中存储在j之间分割成m - 1的最大值。这样状态转移方程变为d[1][j] = max(d[1][j - 1] + e[j], d[0][j - 1] + e[j]);*/#include <iostream>using namespace std;const int nMax = 1000010;const int MIN = -0x7fffffff;int e[nMax];__int64 d[2][nMax];int m, n;int main(){ //freopen("e://data.txt", "r", stdin); while(scanf("%d%d", &m, &n) != EOF) { for(int i = 1; i <= n; ++ i) scanf("%d", &e[i]); memset(d, 0, sizeof(d)); for(int i = 1; i <= m; ++ i) { for(int j = i; j <= n; j ++) { /* for(int k = m - 1; k < j; k ++) { d[1][j] = max(d[0][k] + e[j], d[1][j]); } */ d[1][j] = max(d[0][j - 1] + e[j], d[1][j]); d[1][j] = max(d[1][j - 1] + e[j], d[1][j]);//临界时候已经被包含在内,所以不需要再另外做处理。 } for(int j = i; j <= n; ++ j) { d[0][j] = max(d[0][j - 1], d[1][j]); d[1][j] = MIN; } } /* int _max = 0; for(int i = m; i <= n; ++ i) _max = max(_max, d[0][i]); */ printf("%I64d\n", d[0][n]); } return 0;}
HDOJ 1024 Max Sum Plus Plus
猜你喜欢
转载自hongqiang.iteye.com/blog/1624541
今日推荐
周排行