poj_2479 动态规划
题目大意
给定一列数,从中选择两个不相交的连续子段,求这两个连续子段和的最大值。
题目分析
典型的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 动态规划的更多相关文章
- 增强学习(三)----- MDP的动态规划解法
上一篇我们已经说到了,增强学习的目的就是求解马尔可夫决策过程(MDP)的最优策略,使其在任意初始状态下,都能获得最大的Vπ值.(本文不考虑非马尔可夫环境和不完全可观测马尔可夫决策过程(POMDP)中的 ...
- 简单动态规划-LeetCode198
题目:House Robber You are a professional robber planning to rob houses along a street. Each house has ...
- 动态规划 Dynamic Programming
March 26, 2013 作者:Hawstein 出处:http://hawstein.com/posts/dp-novice-to-advanced.html 声明:本文采用以下协议进行授权: ...
- 动态规划之最长公共子序列(LCS)
转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...
- C#动态规划查找两个字符串最大子串
//动态规划查找两个字符串最大子串 public static string lcs(string word1, string word2) { ...
- C#递归、动态规划计算斐波那契数列
//递归 public static long recurFib(int num) { if (num < 2) ...
- 动态规划求最长公共子序列(Longest Common Subsequence, LCS)
1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...
- 【BZOJ1700】[Usaco2007 Jan]Problem Solving 解题 动态规划
[BZOJ1700][Usaco2007 Jan]Problem Solving 解题 Description 过去的日子里,农夫John的牛没有任何题目. 可是现在他们有题目,有很多的题目. 精确地 ...
- POJ 1163 The Triangle(简单动态规划)
http://poj.org/problem?id=1163 The Triangle Time Limit: 1000MS Memory Limit: 10000K Total Submissi ...
随机推荐
- ASP.NET MVC之Html.RenderAction(无操作方法 传参数)
WEB窗体模式开发惯了,切入MVC模式,好多东西都不懂,每一步都要查资料. 初步得来的一些知识点体会是: _Layout.cshtml就相当于母版页 然后partical视图(部分视图)就是用户控件. ...
- ZOJ 3427 Array Slicing (scanf使用)
题意 Watashi发明了一种蛋疼(eggache) 语言 你要为这个语言实现一个 array slicing 函数 这个函数的功能是 有一个数组初始为空 每次给你一个区间[ l, r) 和 ...
- Content Editor Webpart(一)引用JQuery
SharePoint里面自带了一个Content Editor Webpart, 使用这个webpart.能够方便的往页面上加入随意的内容(HTML,css, JS).以此来达到往页面加入自己定义内容 ...
- 温故而知新 forEach 无法中断(break)的问题
forEach无法使用break和return来中断,只能使用throw catch来达到中断的效果了. var id = (function(){ // forEach 是无法中断的.除非用这种ha ...
- mysql lower_case_table_names ---- 一律把表名处理为小写
一.从操作系统说起: 1.我们知道mysql 是跨平台的.它可以在许多平台上运行如windows .linux.unix(mac).linux 是类unix的, 但是windows和linux就有非常 ...
- Decoration4:分页展示
现在我们实现前台List的分页展示,这也是最基本的要求 先看现在的Rest数据格式,在spring的默认返回中,分页用到的元素都已经在page节点中返回了,只要在前台合理利用就足够了 { " ...
- UIScrollView 的基本用法
转自:http://unmi.cc/use-uiscrollview/ iPhone/iPad 中 UIScrollView 还是经常要用到的,这里作了一个使用它最简单的例子,一个 ScrollVie ...
- iOS之美: UIView 与 UIWindow之间的关系
转自:http://leopard168.blog.163.com/blog/static/168471844201381584533466/ 面对iOS初学者,总会被问到一些不常被关注的问题,比如: ...
- 【C语言】20-static和extern关键字2-对变量的作用
一.在Java中,全局变量的定义没有严格的位置规定 全局变量可以定义在类的最前面,也可以定义在类的最尾端,也就说一个方法可以访问在它之后定义的变量. 可以看到,第4行定义的test方法可以访问第8行定 ...
- java:常用的两种设计模式(单例模式和工厂模式)
一.单例模式:即一个类由始至终只有一个实例.有两种实现方式(1)定义一个类,它的构造方法是私有的,有一个私有的静态的该类的变量在初始化的时候就实例化,通过一个公有的静态的方法获取该对象.Java代码 ...