题意:
     给你一个序列n个数组成,然后让你在里面找到m个子序列,让这m个子序列的和最大。

思路:
      dp[i][j]表示的是第j个数字在第i个子序列时的当前最优值。
dp[i][j] = maxx(dp[i][j-1] + num[j] ,maxx(dp[i-1][k]) + num[j]);  k是从1到j-1.

可以这么理解这个转移方程,对于当前的这个数字,如果把他放到第i个子序列中有两种情况,一个是他作为第i个子序列的第一个数字,另一个就是不作为第一个数字,作为第一个数字的时候是 maxx(dp[i-2][k] + num[j]) 1<=k<i 的意思是从之前的所有中找到i-1个子序列的最大值+当前的值,不做为第一个的时候那么他前面的那个数字一定是i序列的,同一个子序列,又不是作为第一个,那么前面的那个货就一定是同一个子序列的,那么当前的值是dp[i][j-1] + num[j],在两种决策中选择一个最有的就行了,还有就是maxx(dp[i-1][k]+num[j])的这个地方可以开一个数组记录下来,不能每次都跑,跑不起,再有就是这个题目没有给m的范围,所以开不了二维数组(目测不是很大,大的话会超时,但是肯定是先超内存在超时,所以为了保险,还是吧dp[][]压缩成一维的)那么状态转移就边成这样了dp[j]表示的是 j这个人在当前的这个子序列中的最优值,mk[j]表示的是在上一个子序列中1--j的dp的最大值,所以就变成 dp[j] = maxx(dp[j-1] + num[j] ,mk[j-1]+num[j]);还是 max(作为i个子序列的第一个元素,不是第一个元素取一个最大值)。在解释下代码的核心部分。


__int64 Max
for(i = 1 ;i <= m ;i ++) //枚举子序列
{
   Max = - INF;
   for(j = i ;j <= n ;j ++) //j = i是因为每个子序列最少1个元素
   {
       if(i == j) dp[j] = mk[j-1] + num[j];//第i个元素只能是第i个子序列的第一个
       else
       dp[j] = maxx(dp[j-1] ,mk[j-1]) + num[j];
       mk[j-1] = Max; //这个地方注意了,不能更新mk[j],只能更新j-1因为更新j就会被当前的这个子序列更新的时候用到。
       if(Max < dp[j]) Max = dp[j];
   }
}

最后直接输出Max就行了,因为里面保存的正好是第m个子序列中最大的那个。



#include<stdio.h>
#include<string.h>#define N 110000
#define INF 922337203685477580

__int64 num[N] ,dp[N] ,mk[N];__int64 maxx(__int64 x ,__int64 y)
{return x > y ? x : y;
}int main ()
{int n ,m ,i ,j;while(~scanf("%d %d" ,&m ,&n)){for(i = 1 ;i <= n ;i ++)scanf("%I64d" ,&num[i]);memset(dp ,0 ,sizeof(dp));memset(mk ,0 ,sizeof(mk));__int64 Max;for(i = 1 ;i <= m ;i ++){Max = -INF;for(j = i ;j <= n ;j ++){if(i == j) dp[j] = mk[j-1] + num[j];elsedp[j] = maxx(dp[j-1] ,mk[j-1]) + num[j];mk[j-1] = Max;if(Max < dp[j]) Max = dp[j];}}printf("%I64d\n" ,Max);}return 0;
}

hdu1024 最大m子序列和相关推荐

  1. HDU1024 Max Sum Plus Plus【最大子段和+DP】

    Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...

  2. LeetCode简单题之最长和谐子序列

    题目 和谐数组是指一个数组里元素的最大值和最小值之间的差别 正好是 1 . 现在,给你一个整数数组 nums ,请你在所有可能的子序列中找到最长的和谐子序列的长度. 数组的子序列是一个由数组派生出来的 ...

  3. 最长公共子序列(LCS)问题 Longest Common Subsequence 与最长公告字串 longest common substr...

    问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X="x0,x1,-,xm-1",序列Y=& ...

  4. 最长连续子序列nlogn算法

    最长上升子序列(LIS)长度的O(nlogn)算法 标签: 算法search优化存储 2012-04-18 19:38 14031人阅读 评论(5) 收藏 举报  分类: 资料学习(15)  解题报告 ...

  5. 经典dp最长递增子序列

    经典dp最大递增子序列,  看了好长时间,看了好多版本.最终因为这个看懂,也觉得这个是最全面的吧,我感觉我好菜啊. http://wenku.baidu.com/view/bed07b15552707 ...

  6. leetcode-300 最长上升子序列

    题目描述: 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度 ...

  7. leetcode-152 乘积最大子序列

    题目描述: 给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数). 示例 1: 输入: [2,3,-2,4] 输出: 6 解释: 子数组 [2,3] 有最大乘积 6 ...

  8. 无序数组及其子序列的相关问题研究

    算法中以数组为研究对象的问题是非常常见的. 除了排序大家经常会遇到之外, 数组的子序列问题也是其中的一大分类. 今天我就对自己经常遇到的无序数组的子序列相关问题在这里总结一下. 前置条件: 给定无序数 ...

  9. 最长公共上升子序列 LCIS

    关于子序列什么什么的问题,以前一直没怎么在意过,直到省赛突然考了一个赤裸裸的LCIS,这下才着急了,因为忘记怎么做了,而且模版也没有带.从第三名一直掉到第11名,而且超上来的,全都是会做这题的o(╯□ ...

最新文章

  1. 某程序员总结大厂程序员性格:阿里出来的是人精!百度出来的脾气好!美图出来的一根筋!头条出来的心高气傲!京东出来的满嘴是兄弟!...
  2. 【语法】NSString
  3. wxWidgets随笔(13)-wxBoxSizer类Basic Box Sizer(2)
  4. How is XT9 old transaction launched in GRE 210
  5. b站在线解析_这款游戏被全B站所唾弃,每个月却依然有5000万玩家坚持在线?!...
  6. 2、linux网络编程--无连接与面向连接的区别
  7. 非常恶俗地分享一首歌曲(刘亦菲·蝶恋)
  8. 系泊系统悬链线matlab,系泊系统的设计.docx
  9. IDEA------自动导包快捷键
  10. 北京计算机应用基础考试时间,07年北京市自学考试计算机应用基础课周末开考...
  11. [渝粤教育] 西南科技大学 行政法学与行政诉讼法学 在线考试复习资料(1)
  12. 怎么直接运行js文件
  13. stm32寄存器版学习笔记06 输入捕获(ETR脉冲计数)
  14. 多关键词采集搜索引擎URL网址域名
  15. 动画制作·边学习边做动画·从零开始的动画世界
  16. 云计算之路-阿里云上:在乌云中坚信蓝天
  17. java随机中文名_Java随机产生中文昵称
  18. MTK6573智能机平台系统文件夹文件详解3 - App目录
  19. python输出字符串中的大写字母_如何在python中查找字符串中的大写字母
  20. OSDI 2021 VEGITO 论文阅读

热门文章

  1. Laravel Ioc容器singleton和bind方法的区别
  2. 进程内COM与进程外COM
  3. 7.Array 数组对象
  4. Javascript自定义事件功能与用法实例分析
  5. win安装wordcloud报错解决方案
  6. 第十四次ScrumMeeting博客
  7. ES6--基础语法(一)
  8. weboffice 应用
  9. 广州.NET俱乐部活动通知(11月17日)
  10. unittest简单使用的介绍