博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj_2479 动态规划
阅读量:6981 次
发布时间:2019-06-27

本文共 2304 字,大约阅读时间需要 7 分钟。

题目大意

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

题目分析

    典型的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
#include
#define MAX_LEN 50005#define INFINITE 1 << 30#define max(a, b) a > b? a:blong 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;}

 

转载地址:http://ttjpl.baihongyu.com/

你可能感兴趣的文章
阿里游戏云与Intel,iTechClub以及巨人网络共同发布的“TOP游戏”云生态培育计划合作...
查看>>
Hyper-V2:向VM增加虚拟硬盘
查看>>
解决 vs2010 安装过程 提示序列号非法问题
查看>>
flask, SQLAlchemy, sqlite3 实现 RESTful API 的 todo list, 同时支持form操作
查看>>
[转载]AxureRP 7超强部件库下载
查看>>
fiddler https
查看>>
ASP.NET 2.0中合并 GridView 的表头单元格(转)
查看>>
Bboysoul&#39;s Vim使用指南
查看>>
专业的程序员需要具备的思考能力:写一个程序需要注意多少细节问题
查看>>
Android--使用SharedPreferences
查看>>
PXE 自动安装物理机 (DHCP服务由路由提供, 不能再配置)
查看>>
怪异的StackOverflowException异常
查看>>
JAVA操作数据库----- http://blog.sina.com.cn/andyfang
查看>>
使用Linq to Sql 创建数据库和表
查看>>
Java8-Executors-No.02
查看>>
Objective-C:在类中设置不同协议
查看>>
元数据
查看>>
Web Essentials之Browser Link
查看>>
js修改后没反应-看看是不是取的缓存
查看>>
05. Web大前端时代之:HTML5+CSS3入门系列~H5 多媒体系
查看>>