hdu 1024 最大m子段和
注:摘的老师写的
最大m子段和问题
以-1 4 -2 3 -2 3为例
最大子段和是:6
最大2子段和是:4+(3-2+3)=8
所以,最大子段和和最大m子段和不一样,不能用比如先求一个最大子段和,从序列中去掉已求子段,再求下一个最大子段和的方法,这种方法有点贪心的味道,但是不行。所以,还得用动态规划。
1.基本思路:
首先,定义数组num[n],dp[m][n].
num[n]用来存储n个整数组成的序列. dp[m][n]代表n个整数序列求m个子段和。
按照分阶段的思想,我们首先考虑最后一项,即num[n].num[n]属于最大m子段和只有两种情况,
如果用搜索树表示的话,只有两个分支,
一个是属于最大m子段和(肯定是第m子段),
另一个是不属于(即最大m子段和在前n-1个整数中构成)。
先说属于情况,即第m子段由num[n]结尾,又分两种情况:要么自己独立成一个子段,要么与前边以num[j-1]结尾的子段联合。所以,我们用b[m][n]表示最后一个子段以num[n]项结尾的最大m子段和。则
b[m][n]=max{b[m][n-1]+num[n],b[m-1][t]+num[n]},其中后一项表示num[n]自己成一段,前面t个整数(以每个整数为子段最后一项)(1<=t<=n-1)。
再说不属于情况,则dp[m][n]=dp[m][n-1],表示由n-1个整数构成m个子段和最大。(不包括num[n])
综合这两种情况:
dp[m][n]=max{b[m][n-1]+num[n],b[m-1][t]+num[n],dp[m][n-1]}
推广一下:
dp[i][j]=max{b[i][j],dp[m][n-1]}=max{b[i][j-1]+num[j],b[i-1][t]+num[j],dp[i][j-1]}
dp[0][1]=dp[1][0]=0
b[0][1]=b[1][0]=0
以下,验证一下:
以4 -2 3 -2 3为例
dp[1][1]=max{b[1][0]+4,b[0][0]+4,0}=4 b[1][1]=4
dp[1][2]=max{b[1][1]-2,(b[0][0],b[0][1])+4,dp[1][1]}=4 b[1][2]=4-2=2
dp[1][3]=max{b[1][2]+3,(b[0][0],b[0][1],b[0][2])+4,dp[1][2]}=max{5,4,4}=5 b[1][3]=5
dp[1][4]=max{b[1][3]-2,(b[0][0],b[0][1],b[0][2],b[0][3])+4,dp[1][3]}=max{3,4,5}=5 b[1][4]=3
dp[1][5]=max{b[1][4]+3,(b[0][0],b[0][1],b[0][2],b[0][3],b[0][4])+4,dp[1][4]}=max{6,4,5}=6 b[1][5]=6
dp[2][1]=0 b[2][1]=0
dp[2][2]=max{b[2][1]-2,(b[1][0],b[1][1])-2,dp[2][1]}=max{-2,2,0}=2 b[2][2]=2
dp[2][3]=max{b[2][2]+3,(b[1][0],b[1][1],b[1][2])+3,dp[2][2]}=max{5,7,2}=7 b[2][3]=7
dp[2][4]=max{b[2][3]-2,(b[1][0],b[1][1],b[1][2],b[1][3])-2,dp[2][3]}=max{5,3,7}=7 b[2][4]=5
dp[2][5]=max{b[2][4]+3,(b[1][0],b[1][1],b[1][2],b[1][3],b[1][4])+3,dp[2][4]}=max{8,8,7}=8 b[2][5]=8
验证表明,分析正确。
但是,我们会发现,当n非常大时,这个算法的时间复杂度和空间复杂度是非常高的,时间复杂度近似为O(m*n^2),
空间复杂度近似为O(m*n).因此,我们需要优化算法来降低时间复杂度和空间复杂度.
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int curr[],pre[],arr[];
const int MAX = -;
int sum = ;
int main()
{
int m,n;
while(cin>>m>>n)
{
memset(curr,,sizeof(curr));
memset(pre,,sizeof(pre));
for(int i=;i<=n;i++)
cin>>arr[i];
int j=;
for(int i=;i<=m;i++)
{
sum = MAX;
for(j=i;j<=n;j++)
{
curr[j] = max(curr[j-],pre[j-])+arr[j];
pre[j-] = sum;
sum = max(sum,curr[j]);
}
pre[j-] = sum; }
cout<<sum<<endl;
}
}
hdu 1024 最大m子段和的更多相关文章
- hdu 1024 最大M子段dp
题目: Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Ot ...
- HDU 1024 max sum plus
A - Max Sum Plus Plus Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I6 ...
- HDU 1024 Max Sum Plus Plus --- dp+滚动数组
HDU 1024 题目大意:给定m和n以及n个数,求n个数的m个连续子系列的最大值,要求子序列不想交. 解题思路:<1>动态规划,定义状态dp[i][j]表示序列前j个数的i段子序列的值, ...
- 怒刷DP之 HDU 1024
Max Sum Plus Plus Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
- 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" ...
- 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 ...
- (最大m子段和) 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/ ...
- 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/ ...
随机推荐
- A. Amr and Music
解题思路:给出n种乐器学习所需要的时间,以及总共的天数, 问最多能够学多少门乐器,并且输出这几门乐器在原序列中的序号(不唯一) 按照升序排序,为了学到最多的乐器,肯定要选择花费时间最少的来学习 然后用 ...
- Servlet中文乱码原因 解决 Get 和 Post 和客户端
一.Get方式的中文乱码 1) 使用如下页面表单内容: <form action="http://127.0.0.1:8080/day07/params" method=&q ...
- Unknown column 't_user.id' in 'where clause'(通过字段名删除不了数据)
创建员工信息表t_user CREATE TABLE t_user( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(20) , passwor ...
- 路飞学城Python-Day14(practise)
本章总结 练习题 1.logging模块有几个日志级别? 5个,按级别从高到低分别是 CRITICAL(灾难)>ERROR(错误)>WARNING(警示)>INFO(信息)>D ...
- js对象追加到数组里
描述:将一个点击事件得到的对象追加到数组里 做法:全局声明一个数组,,在对象的点击事件里将得到的对象追加到数组 change(a){ arr.push(a) console.log(arr) var ...
- layui计算剩余时间
<div id="test"></div> <script> layui.use('util', function(){ var util = ...
- CF1005F Berland and the Shortest Paths (树上构造最短路树)
题目大意:给你一个边权为$1$的无向图,构造出所有$1$为根的最短路树并输出 性质:单源最短路树上每个点到根的路径 ,一定是这个点到根的最短路之一 边权为$1$,$bfs$出单源最短路,然后构建最短路 ...
- linux 系统相关命令
说明:此篇以 Debian ( ubuntu16.04 ) 命令为例 1. tab键默认是不能自动补全命令 apt install bash-completion // 安装完成之后重启系统 2. 虚 ...
- 【BZOJ 1406】 [AHOI2007]密码箱
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] \(x^2%n=1\) \(x^2-1 = k*n\) \((x+1)*(x-1) % n == 0\) 设\(n=a*b\) 对于 ...
- 【codeforces 46C】Hamsters and Tigers
[题目链接]:http://codeforces.com/problemset/problem/46/C [题意] 给你一个长度为n的01串; 让你把所有的0放在一起,把所有的1放在一起; (即0都是 ...