(动态规划)Max Sum Plus Plus--hdu--1024
http://acm.hdu.edu.cn/showproblem.php?pid=1024
Max Sum Plus Plus
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 21363 Accepted Submission(s): 7144
Given a consecutive number sequence S1, S2, S3, S4 ... Sx, ... Sn (1 ≤ x ≤ n ≤ 1,000,000, -32768 ≤ Sx ≤ 32767). We define a function sum(i, j) = Si + ... + Sj (1 ≤ i ≤ j ≤ n).
Now given an integer m (m > 0), your task is to find m pairs of i and j which make sum(i1, j1) + sum(i2, j2) + sum(i3, j3) + ... + sum(im, jm) maximal (ix ≤ iy ≤ jx or ix ≤ jy ≤ jx is not allowed).
But I`m lazy, I don't want to write a special-judge module, so you don't have to output m pairs of i and j, just output the maximal summation of sum(ix, jx)(1 ≤ x ≤ m) instead. ^_^
Process to the end of file.
w[i][j]: 前 j 个数分为 i 段, 第 j 个数必须选;1. 第 j 个数单独为1段;2. 第 j 个数与前面的数连一块。
w[i][j] = max(b[i-1][j-1], w[i][j-1]) + a[j];
b[i][j]:前 j 个数分为 i 段, 第 j 个数可选可不选; 1.选第 j 个数;2.不选第 j 个数。
b[i][j] = max(b[i][j-1], w[i][k]);
/// w[j] 表示 j 个元素取 i 段, a[j] 必须取是的最大值
w[j] = max(dp[1-t][j-1], w[j-1]) + sum[j]-sum[j-1];
/// dp[t][j] 表示在a[j]可取可不取这两种情况下取得的最大值
dp[t][j] = max(dp[t][j-1], w[j]);
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 1000001
using namespace std; int sum[N], w[N], dp[][N]; ///sum[i] 里面存的是前 i 项和 int main()
{
int m, n; while(scanf("%d%d", &m, &n)!=EOF)
{
int i, j, x; sum[] = ;
for(i=; i<=n; i++)
{
scanf("%d", &x);
sum[i] = sum[i-] + x;
dp[][i] = ; ///从前 i 个元素中取 0 段, 最大值为 0
} /** 我们先假设a[i]中 存放该序列的第 i 个值,
w[i][j] 表示前 j 个数分为 i 段, 第 j 个数必须选这种情况下取得的最大值
b[i][j]表示在前 j 个数中取 i 段 这种情况写取得的最大值 w[i][j]: 前 j 个数分为 i 段, 第 j 个数必须选;1. 第 j 个数单独为1段;2. 第 j 个数与前面的数连一块。
w[i][j] = max(b[i-1][j-1], w[i][j-1]) + a[j];
b[i][j]:前 j 个数分为 i 段, 第 j 个数可选可不选; 1.选第 j 个数;2.不选第 j 个数。
b[i][j] = max(b[i][j-1], w[i][j]); **/ int t=;
for(i=; i<=m; i++) /// i表示取 i 段
{
for(j=i; j<=n; j++) /// 如果dp[i][j](j<i)是没有意义的
{
if(i==j)
dp[t][j] = w[j] = sum[j];
else
{
/// w[j] 表示 j 个元素取 i 段, a[j] 必须取是的最大值
w[j] = max(dp[-t][j-], w[j-]) + sum[j]-sum[j-];
/// dp[t][j] 表示在a[j]可取可不取这两种情况下取得的最大值
dp[t][j] = max(dp[t][j-], w[j]);
}
}
t = -t; ///t在 0 和 1 直间交替变换 /** 为什么要交换呢??? 这是为了要节省空间
仔细观察递归式
w[i][j] = max(b[i-1][j-1], w[i][j-1]) + a[j];
b[i][j] = max(b[i][j-1], w[i][j]);
我们发现,对于取 i 段, w[i][j] 只与 b[i-1][k-1] 和 w[i][k-1] 有关, 与之前的那一些项没有关系
因此我们的数组可以开小一点, 用更新来覆盖掉前面的值!!! **/
} printf("%d\n", dp[m%][n]);
}
return ;
}
(动态规划)Max Sum Plus Plus--hdu--1024的更多相关文章
- Max Sum Plus Plus HDU - 1024
Max Sum Plus Plus HDU - 1024 Now I think you have got an AC in Ignatius.L's "Max Sum" ...
- 最大m段子段和 Day9 - E - Max Sum Plus Plus HDU - 1024
Now I think you have got an AC in Ignatius.L's "Max Sum" problem. To be a brave ACMer, we ...
- Max Sum Plus Plus HDU - 1024 基础dp 二维变一维的过程,有点难想
/* dp[i][j]=max(dp[i][j-1]+a[j],max(dp[i-1][k])+a[j]) (0<k<j) dp[i][j-1]+a[j]表示的是前j-1分成i组,第j个必 ...
- C - Max Sum Plus Plus HDU - 1024
用二位数组dp[i][j]记录组数为i,前j个数字的最大子段和. 转移方程: dp[i][j],考虑第j个数,第j个数可以并到前面那一组,此时dp[i][j]=dp[i][j-1]+arr[j],第j ...
- HDU 1024 Max Sum Plus Plus【动态规划求最大M子段和详解 】
Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- HDU 1024 Max Sum Plus Plus (动态规划)
HDU 1024 Max Sum Plus Plus (动态规划) Description Now I think you have got an AC in Ignatius.L's "M ...
- HDU 1024 Max Sum Plus Plus (动态规划、最大m子段和)
Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- HDU 1024 Max Sum Plus Plus [动态规划+m子段和的最大值]
Max Sum Plus Plus Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tot ...
- hdu 1024 Max Sum Plus Plus (动态规划)
Max Sum Plus PlusTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- HDU 1024 Max Sum Plus Plus (动态规划 最大M字段和)
Problem Description Now I think you have got an AC in Ignatius.L's "Max Sum" problem. To b ...
随机推荐
- mysql 添加权限和撤销权限的实例(亲测可行)
将当前数据库的表role_modules 的select权限赋予给用户uwangq: GRANT SELECT ON role_modules TO uwangq@'%' IDENTIFIED BY ...
- 21.Mysql Server优化
21.优化Mysql Server21.1 Mysql体系结构概览Mysql由Mysql Server层和存储引擎层组成.Mysql实例由一组后台进程.一写内存块和若干服务线程组成.Mysql后台进程 ...
- (O)js核心:作用域链
作用域 在一个函数被调用的时候,函数的作用域才会存在.此时,在函数还没有开始执行的时候,开始创建函数的作用域: 函数作用域的创建步骤: 1.函数形参的声明. 2.函数变量的声明. 3.普通变量的声 ...
- usr/include/c++/6.4.1/bits/stl_relops.:67: Parse error at "std"
问题描述: 1.编译某qt工程的32位架构二进制包时,出现了上面错误,具体错误信息如下 qmake-qt5 -o ProductLicense/Makefile ProductLicense/Prod ...
- linux查看文件被哪个进程占用?
1> 如果文件是端口号 netstat -ntlp | grep portNum [root@localhost root]# netstat -ntlp Active Internet con ...
- holiday(假期)_题解
holiday(假期) —— 一道妙题(codevs3622) Description 经过几个月辛勤的工作,FJ 决定让奶牛放假.假期可以在1…N 天内任意选择一段(需要连续),每一天都有一个享 ...
- socket 长连接
实现: 长连接的维持,是要客户端程序,定时向服务端程序,发送一个维持连接包的. 如果,长时间未发送维持连接包,服务端程序将断开连接. 服务端: 由于客户端会定时(keepAliveDelay毫秒)发送 ...
- mysql 设置用户并授权
一, 创建用户: 命令:CREATE USER 'username'@'host' IDENTIFIED BY 'password'; 说明:username - 你将创建的用户名, host - 指 ...
- [ES]elasticsearch章2 ES查询过程解析
es服务端是准确知道每个document分布在哪个shard上: search一个比较复杂的执行模式,因为我们不知道那些document会被匹配到,任何一个shard上都有可能,所以一个search请 ...
- where_1
(二)WHERE //where不单独使用,与match,optional match,start,with搭配 where 与match,optional match 一起用,表示约束 where ...