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)
Total Submission(s): 44371 Accepted Submission(s): 16084
Problem Description
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. ^_^
Input
Process to the end of file.
Output
Sample Input
- - -
Sample Output
题目大意
从一序列中取出若干段,这些段之间不能交叉,使得和最大并输出。、
题目分析
动态规划 首先我们可以列出最基本的状态转移方程:
dp[i][j] = max( dp[i][j-1] + a[j] , dp[i-1][k] + a[j ]) i-1<=k<=j-1
这个方程的含义是:
dp[i][j] 是将前 j 个数分成 i 份,且第 i 份包含第 j 个数 的情况下的最大值
那么对于第 j 个数来说,就有两个选择:
作为第 i 份的一部分 :也就是将前 j-1 个数分成 i 份 且第 j-1 个数属于第 i 份 即 dp[i][j-1]
或者单独出来成为第 i 份:也就是将前 j-1 个数分成 i-1 份 且第 j-1 个数不一定属于第 i-1 份 即 dp[i-1][k] i-1<=k<=j-1
但是这个方程不仅时间复杂度高,空间复杂度也高的可怕 这是不行的
所以我们要将其优化:
首先我们发现 dp[i][j] 只需要比较 dp[i][j-1] 与 dp[i-1][k] 的最大值即可 而这个 dp[i-1][k] 的最大值是可以记录下来的 不需要遍历 这就砍去了一层循环
所以我们只需要定义一个 pre[n] 数组 用 pre[j] 来存储第 j-1 个数被分成 i-1 份时的最大值即可
于此同时 在计算 dp[i][j] 时,我们可以计算出 dp[i][k] i<=k<=j 的值 而这个值是在之后我们要计算 dp[i+1][j+1] 时 要使用的 pre[j]
现在状态转移方程变成了:
dp[i][j] = max( dp[i][j-1] + a[j] , pre[j-1] + a[j ])
现在我们发现 由于pre[j] 的存在 似乎已经不需要 dp[i][j] 这个庞大的二维数组了 只需要开一个 dp[n] 的数组 用dp[j]来存储dp[i][j]即可,因为当前的转移方程根本就没有用到 i 这一维!
这样的话 转移方程又变成了:
dp[j] = max( dp[j-1] + a[j] , pre[j-1] + a[j ])
不过 i 的这一层循环还是得循环的 这个砍不掉的...
#include<bits/stdc++.h> using namespace std; int n,m,dp[],a[],pre[],i,j,temp; int main()
{
while(scanf("%d %d",&m,&n)!=EOF)
{
memset(dp,,sizeof(dp));
memset(a,,sizeof(a));
memset(pre,,sizeof(pre));
for(i=;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(i=;i<=m;i++)
{
temp=-0x7ffffff;
for(j=i;j<=n;j++)
{
dp[j]=max(dp[j-],pre[j-])+a[j];
pre[j-]=temp;
temp=max(temp,dp[j]);
}
}
cout<<temp<<endl;
}
}
HDU 1024 Max Sum Plus Plus (动态规划、最大m子段和)的更多相关文章
- HDU 1024 Max Sum Plus Plus(m个子段的最大子段和)
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1024 Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/ ...
- 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 ...
- HDU - 1024 Max Sum Plus Plus 最大m段子段和+滚动数组优化
给定n个数字,求其中m段的最大值(段与段之间不用连续,但是一段中要连续) 例如:2 5 1 -2 2 3 -1五个数字中选2个,选择1和2 3这两段. dp[i][j]从前j个数字中选择i段,然后根据 ...
- 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 --- dp+滚动数组
HDU 1024 题目大意:给定m和n以及n个数,求n个数的m个连续子系列的最大值,要求子序列不想交. 解题思路:<1>动态规划,定义状态dp[i][j]表示序列前j个数的i段子序列的值, ...
- 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
A - Max Sum Plus Plus Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I6 ...
随机推荐
- python--Excel模块xlwings
安装:pip install xlwings 基本操作: xlwings的特色: xlwings能够非常方便的读写Excel文件中的数据,并且能够进行单元格格式的修改 可以和matplotlib以及p ...
- web前端_js
在HTML中可以将JavaScript/JS的代码写在head中,被script标签所包裹,当浏览器解释HTML时,遇到style标签时,按照CSS规则解释,遇到Script标签时,按照JavaScr ...
- 窗体操作:CBrush类
CBrush画刷定义了一种位图形式的像素,利用它可对区域内部填充颜色. 该类封装了Windows的图形设备接口(GDI)刷子.通过该类构造的CBrush对象可以传递给任何一个需要画刷的CDC成员函数. ...
- 【CF963C】Cutting Rectangle(数论,构造,map)
题意: 思路:考虑构造最小的单位矩形然后平铺 单位矩形中每种矩形的数量可以根据比例算出来,为c[i]/d,其中d是所有c[i]的gcd,如果能构造成功答案即为d的因子个数 考虑如果要将两种矩形放在同一 ...
- NOI数论姿势瞎总结(Pi也没有)
Miller-Rabin素数检测 费马小定理:没人不会吧. 二次探测:如果\(n\)是质数,\(x^2 \equiv 1\ (\mod n)\)的解只有\(x \equiv 1\)或\(x \equi ...
- 9.Python关键字(保留字)一览表
保留字是 Python 语言中一些已经被赋予特定意义的单词,这就要求开发者在开发程序时,不能用这些保留字作为标识符给变量.函数.类.模板以及其他对象命名. Python 包含的保留字可以执行如下命令进 ...
- linux pwd指令的C实现
linux pwd指令的C实现 pwd指令的功能介绍 linux pwd命令用于显示工作目录 执行pwd命令可立刻得知当前所在工作目录的绝对路径名称. 示例: 查询系统手册 如图所示,getcwd的描 ...
- 设置Google浏览器不缓存JS
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...
- 第七周总结&实验报告5
这一周的课程内容比较难,而且比较不容易理解,所有学习的很吃力,现在接触的知识越来越多,也越来越难了,还是要多对照书本来进行学习! 这周主要学的有: 一.抽象类 1.Java中可以创建一种类专门用来当作 ...
- SpringBoot整合kafka(安装)
项目路径:https://github.com/zhaopeng01/springboot-study/tree/master/study_14 序言 Kafka 是一种高吞吐的分布式发布订阅消息系统 ...