题目大意

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

题目分析

典型的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. 转 Android开发学习笔记:浅谈WebView

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://liangruijun.blog.51cto.com/3061169/647456 ...

  2. java dom xml解析和windows dom解析的差别

    1.java dom 子节点包括空节点. 2.java dom 文档节点值也是其的子节点. 而windows dom(mshtml.dll)子节点不包括空节点,而节点值也不是以子节点的方式来对待的.

  3. quartz cron表达式在线生成

    近期使用了quartz定时器,有感于起cron表达式有点复杂.且无法实时推断定时时间是否正确,因此写了个在线表达式及依据表达式获得前10次运行时间. 訪问地址例如以下:http://cron.g2ro ...

  4. SIP/2.0 403 Forbidden(Invalid domain in From: header)

    一.错误场景 FreeSWITCH通过网关和一台支持SIP的网关设备互联,一个呼叫发过去,收到这个错误. FreeSWITCH的地址是192.168.1.99. 网关设备的地址是192.168.1.2 ...

  5. linux学习规划

  6. pcie dma的玩法

    There is some issue with the implement script. So I took the manual steps. 1. Created the pcie core ...

  7. C数据结构-栈和队列,括号匹配举例---ShinePans

    1.栈和队列是两种特殊的线性表             运算操作被限定仅仅能在表的一端或两端插入,删除元素,故也称它们为限定的线性表结构 2.栈的基本运算 1).Stackinit(&s) 构 ...

  8. 56. Two Sum【easy】

    Given an array of integers, find two numbers such that they add up to a specific target number. The ...

  9. python中sorted方法和列表的sort方法使用详解

    一.基本形式 列表有自己的sort方法,其对列表进行原址排序,既然是原址排序,那显然元组不可能拥有这种方法,因为元组是不可修改的. 排序,数字.字符串按照ASCII,中文按照unicode从小到大排序 ...

  10. html5 indexDB的使用

    angular.module('indexdb', []) .factory('indexDbJs', [function() { const CurDBVersion = 10000; window ...