hdu 1024 从一个序列中选择m个序列不交叉,就最大值
来源:互联网 发布:重要经济数据公布时间 编辑:程序博客网 时间:2024/06/05 19:02
hdu 1024(最大和连续子序列增强版)
题意:最大和连续子序列的增强版,要求从一序列中取出若干段,这些段之间不能交叉,使得和最大并输出。
分析:用dp[i][j]表示前j个数取出i段得到的最大值,那么状态转移方程为dp[i][j]=max(dp[i][j-1]+a[j],dp[i-1][k]+a[j]) i-1<=k<=j-1
这个状态转移方程表达了两种不同的选择:第一个就是第j个连在第j-1个所在的段的后面,第二个就是第j个为新的一段的第一个数字。
由于数字的个数比较大,而题目中给定的m未知,怕超内存,所以要想办法开设一维数组来代替,后来发现可以用dp[j]表示表示到第j个的时候
最大和。解决了空间的问题了,现在就是时间的问题了,dp[i-1][k] i-1<=k<=j-1,如果这里用for循环去写的话,由于题目中给定的数字个数
太大,那肯定会超时的!所以我们可以开设一个数组来记录上一状态的j-1个前的最大值,具体看代码实现吧!!
代码实现:
#include<iostream>#include<string.h>#include<stdio.h>using namespace std;int a[1000001],dp[1000001],max1[1000001];int max(int x,int y){ return x>y?x:y;}int main(){ int i,j,n,m,temp; while(scanf("%d%d",&m,&n)!=EOF) { for(i=1;i<=n;i++) { scanf("%d",&a[i]); dp[i]=0; max1[i]=0; } dp[0]=0; max1[0]=0; for(i=1;i<=m;i++)//这里可以省空间 { temp=-100000000; for(j=i;j<=n;j++) { dp[j]=max(dp[j-1]+a[j],max1[j-1]+a[j]); max1[j-1]=temp;//为i+1的时候做准备 temp=max(temp,dp[j]);//保存前j个段数为i时的最大值 } } printf("%d\n",temp); } return 0;}
阅读全文
0 0
- hdu 1024 从一个序列中选择m个序列不交叉,就最大值
- hdu 1024 Max Sum Plus Plus (求一个序列中选出的m个不相交子段和的最大值)
- HDU 1024 给定一个数组,求其分成m个不相交子段和最大值
- HDU 1024 Max Sum Plus Plus(求m个不相交连续子序列最大和/01背包)
- HDU 1024(动态规划+滚动数组+决策优化,求m个不相交字段和最大值)
- HDU 1024 Max Sum Plus Plus(动态规划,给定一个数组,求其分成m个不订交子段和最大值的题目)
- hdu 1024 DP 求n个数m个不交叉子段的最大和
- 求一个数组中序列连续数的最大值
- hdu 1024 Max Sum Plus Plus(dp求m个不相交子段和的最大值)
- 从数字1到N的序列中添加+或-,使得序列的和等于M
- 从n个数字中选取m个数字的组合算法(不分序列)
- 从n个数中选择随机选择m个, m个数互不重复
- hdu 1024 Max Sum Plus Plus 最大m个子序列
- 查找一个序列的最大值和最小值
- M序列
- M序列
- m序列
- m序列
- S01开始
- 腾讯的乘法效应:在开放后,走向“再开放”
- 为什么每平方英尺的Apple Store值一辆奔驰?
- 任天堂:我们不准备亏本销售NX游戏主机
- 无人机的天敌,让你知道无人机是怎么被打下来的
- hdu 1024 从一个序列中选择m个序列不交叉,就最大值
- vue+cordova创建Hybird混合应用(一)----安装cordova环境
- CocosCreator H5 微信内置浏览器调起微信支付
- 《中国众创空间发展白皮书》:双创经济步入“生态资源分享”时代
- 英文文档的阅读
- 本周锋玩:和无人机比,智能手机简直土到掉渣
- 【盘点】5款曾爆红的无人机,一个比一个会拍宣传片
- UML
- 国外创业者都在做什么样的机器人