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 ...
随机推荐
- JEECG与帆软报表集成
将FineReport 集成到自己的web项目中,生成报表,可以方便快捷的和自己的项目融合在一起.简化了利用poi的导出遇到的问题. 1.首先在FR中建立好一个模板 例如:我的这张模板是连接 ...
- REST 和 SOAP、RPC 有何区别?
第一个问题:什么是RESTful? REST这个词,是Roy Thomas Fielding在他2000年的博士论文中提出的.有兴趣可以看看这里论文`,谁是Fielding?点击前面名字了解. 那RE ...
- 又是一年WWDC,暨回想去年之旅——Part III
前言 无论这篇写到哪里,就以这篇作为结尾,结束这个流水回想系列文了. Computer History Museum 计算机历史博物馆(站点)是在Google旁边,參观Google之前的行程. 记得那 ...
- 微服务实战-使用API Gateway
当你决定将应用作为一组微服务时,需要决定应用客户端如何与微服务交互.在单体式程序中,通常只有一组冗余的或者负载均衡的服务提供点.在微服务架构中,每一个微服务暴露一组细粒度的服务提供点.在本篇文章中,我 ...
- Linux下编译C++程序遇到错误:undefined reference to `*::*
“undefined reference to”的意思是,该函数未定义. 如果使用的是g++,有以下检查方案: 如果提示未定义的函数是某个库的函数.检查库是否已经安装,并在编译命令中采用-l和-L参数 ...
- 折腾kali linux2.0
偶然的机会了解到了kali linux这个用于渗透测试的linux发行版,于是就从官网下了iso,但是制作启动盘老出错.网上查了下说在linux下用dd命令特别简单,于是转到ubuntu下制作启动盘, ...
- Flashtext 使用文档 大规模数据清洗的利器-实现文本结构化
1.1 安装 pip install flashtext 1.2 使用例子 1.2.1 关键字提取 >>> from flashtext import KeywordProcesso ...
- C#里面的枚举与位或运算符 一个枚举变量存入多个值
以前我们如果定义一个枚举类型 ,然后定义一个枚举变量,那么这个枚举变量只能为类型中的一个值,现在我们想要一个变量能够代表多个值: 今天看<Pro Net 2.0 Windows Forms An ...
- linux udhcpc 后无法自动设置网卡ip
arm 主板用 udhcpc 获取租赁的空闲的ip后,并没有直接设置在网卡上. 查了一下相关原因,是因为虽然已经获取了ip, 但是并没有通过脚本去设置这个IP. 在 busybox 里面有相关的脚本要 ...
- sama5 kio接口控制
//example #include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <str ...