题目大意

给定一列数,从中选择两个不相交的连续子段,求这两个连续子段和的最大值。

题目分析

典型的M子段和的问题,使用动态规划的方法来解决。

f[i][j] 表示将A[1...i] 划分为j个不相交连续子串,且A[j]属于第i个子串,所能达到的最大子串和 
g[i][j] 表示将A[1...j]划分为i个不相交连续子串,且A[j]不一定属于第i个子串,所能达到的最大子串和 
f[i][j] = max{f[i-1][j] + A[i], g[i-1][j-1] + A[i]} 
g[i][j] = max{g[i-1][j], f[i][j]}; 
进行空间优化之后: 
f[j] = max{f[j], g[j-1]} + A[i] 
g[j - 1] = max(g[j - 1], f[j - 1]); 
注意f和g的循环层次不同.这是因为:在外部进行到第i层循环的时候,f[i][j] = max{f[i-1][j] + A[i], g[i-1][j-1] + A[i]} 中max{}中的 f[j]和g[j-1]用的是第i-1层循环的时候的 f[j]和 g[j-1]; 若写成f[j] = max(f[j] + A[i], g[j - 1] + A[i]);g[j] = max(g[j], f[j]); 
则本次的g[j]变成了第i次循环的g[j],而下次循环的 f[j] = max{} 中g[j-1]变成了第i次循环的g[j],而不是第i-1次循环的g[j]因此,写成 g[j-1] = max(g[j-1], f[j-1]); 使得 每次执行 
for (j = 1; j <= m; j++){ 
f[j] = max(f[j] + A[i], g[j-1] + A[i]); 
g[j-1] = max(g[j-1], f[j-1]); 

的时候, f[j]都使用第i-1层的f[j]和g[j-1],而g[j-1]使用的是第i-1层的g[j-1]和第i层的f[j]

实现(c++)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#define MAX_LEN 50005
#define INFINITE 1 << 30
#define max(a, b) a > b? a:b
long long int f[MAX_LEN];
long long int g[MAX_LEN];
int A[MAX_LEN];
/*f[i][j] 表示将A[1...i] 划分为j个不相交连续子串,且A[j]属于第i个子串,所能达到的最大子串和
g[i][j] 表示将A[1...j] 划分为i个不相交连续子串,且A[j]不一定属于第i个子串,所能达到的最大子串和
f[i][j] = max{f[i-1][j] + A[i], g[i-1][j-1] + A[i]}
g[i][j] = max{g[i-1][j], f[i][j]};
进行空间优化之后:
f[j] = max{f[j], g[j-1]} + A[i]
g[j - 1] = max(g[j - 1], f[j - 1]);
注意f和g的循环层次不同
这是因为:在外部进行到第i层循环的时候,f[i][j] = max{f[i-1][j] + A[i], g[i-1][j-1] + A[i]} 中max{}中的 f[j]和g[j-1]用的是
第i-1层循环的时候的 f[j]和 g[j-1];
若写成
f[j] = max(f[j] + A[i], g[j - 1] + A[i]);
g[j] = max(g[j], f[j]);
则本次的g[j]变成了第i次循环的g[j],而下次循环的 f[j] = max{} 中 g[j-1]变成了第i次循环的g[j],而不是第i-1次循环的g[j]
因此,写成 g[j-1] = max(g[j-1], f[j-1]); 使得 每次执行
for (j = 1; j <= m; j++){
f[j] = max(f[j] + A[i], g[j-1] + A[i]);
g[j-1] = max(g[j-1], f[j-1]);
}
的时候, f[j]都使用第i-1层的f[j]和g[j-1],而g[j-1]使用的是第i-1层的g[j-1]和第i层的f[j]
*/
long long int MaxSum(int m, int n){
int i, j;
for (i = 1; i <= n; i++){
for (j = 1; j <= m; j++){
f[j] = max(f[j] + A[i], g[j-1] + A[i]);
g[j-1] = max(g[j-1], f[j-1]);
}
g[j - 1] = max(g[j - 1], f[j - 1]);
}
return g[m];
} int main(){
int cas;
scanf("%d", &cas);
while (cas--){
int n;
scanf("%d", &n); f[0] = g[0] = 0;
for (int i = 1; i <= n; i++){
f[i] = g[i] = -INFINITE;
scanf("%d", A + i);
}
long long int max_sum = MaxSum(2, n);
printf("%lld\n", max_sum);
}
return 0;
}

poj_2479 动态规划的更多相关文章

  1. 增强学习(三)----- MDP的动态规划解法

    上一篇我们已经说到了,增强学习的目的就是求解马尔可夫决策过程(MDP)的最优策略,使其在任意初始状态下,都能获得最大的Vπ值.(本文不考虑非马尔可夫环境和不完全可观测马尔可夫决策过程(POMDP)中的 ...

  2. 简单动态规划-LeetCode198

    题目:House Robber You are a professional robber planning to rob houses along a street. Each house has ...

  3. 动态规划 Dynamic Programming

    March 26, 2013 作者:Hawstein 出处:http://hawstein.com/posts/dp-novice-to-advanced.html 声明:本文采用以下协议进行授权: ...

  4. 动态规划之最长公共子序列(LCS)

    转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...

  5. C#动态规划查找两个字符串最大子串

     //动态规划查找两个字符串最大子串         public static string lcs(string word1, string word2)         {            ...

  6. C#递归、动态规划计算斐波那契数列

    //递归         public static long recurFib(int num)         {             if (num < 2)              ...

  7. 动态规划求最长公共子序列(Longest Common Subsequence, LCS)

    1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...

  8. 【BZOJ1700】[Usaco2007 Jan]Problem Solving 解题 动态规划

    [BZOJ1700][Usaco2007 Jan]Problem Solving 解题 Description 过去的日子里,农夫John的牛没有任何题目. 可是现在他们有题目,有很多的题目. 精确地 ...

  9. POJ 1163 The Triangle(简单动态规划)

    http://poj.org/problem?id=1163 The Triangle Time Limit: 1000MS   Memory Limit: 10000K Total Submissi ...

随机推荐

  1. 用C语言实现循环左移和循环右移

    有天重建一段代码时,遇到了循环右移指令,不知道用C语言怎么实现,后来得到小伟指点,感谢.. me 15:56:38004BD2C9 8B55 F8 MOV EDX,DWORD PTR SS:[EBP- ...

  2. Mybatis自动生成的配置实例

    一.目录 按照图片准备下面的东西吧,基础jar,数据链接库的jar. 二.generatorConfig.xml <?xml version="1.0" encoding=& ...

  3. spring in action 7.1 小结

    0 AbstractAnnotationConfigDispatcherServletInitializer剖析,在Servlet 3.0环境中,容器会在类路径中查找实现ServletContaine ...

  4. Java中RunTime类介绍

    Runtime 类代表着Java程序的运行时环境,每个Java程序都有一个Runtime实例,该类会被自动创建,我们可以通过Runtime.getRuntime() 方法来获取当前程序的Runtime ...

  5. Lattice 开发工具Diamond 相关版本下载地址

    百度网盘: https://wenku.baidu.com/view/21b98975192e45361066f5f3.html 官网下载: http://www.latticesemi.com/Su ...

  6. shell获取用户输入

    主题: 再学shell之获取用户输入echo -n(不换行)和read命令-p(提示语句) -n(字符个数) -t(等待时间) -s(不回显) 和“读文件”深入学习 1.基本读取read命令接收标准输 ...

  7. JAX-WS使用Handler实现简单的WebService权限验证

    WebService如果涉及到安全保密或者使用权限的时候,WS-Security通常是最优选择.WS-Security (Web服务安全) 包含了关于如何在WebService消息上保证完整性和机密性 ...

  8. windows phone 切换多语言时,商店标题显示错误的问题

    前段时间,用业余时间写了一款 wp8 app(“超级滤镜”商店,中文地址:英文地址),在多语言的时候,给 app title 和 app tile title 进行多语言时(参考 MSDN),中文商店 ...

  9. Hive使用过程中的坑

    在Hive脚本中如果有 use db; #即使用数据库 最后一定要有一个exit;脚本,退出hive窗口 否则运行到最后,hive无法启动MR任务,只是卡在打印完成hive脚本处. 例子如下: $Hi ...

  10. ParagraphFormat 对象【精品】

    ParagraphFormat 对象 贡献者:motolola   日期:2009-05-27  阅读:5261  回复: 相关标签:wps  >  API  >  paragraphfo ...