hdu1024 最大m子序列和
题意:
给你一个序列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];
else
dp[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子序列和的更多相关文章
- 最大m段子段和
hdu1024 最大m子序列和 给定你一个序列,让你求取m个子段(不想交的子段)并求取这m个子段和的最大值 从二维开始来看dp[i][j]表示取第j个数作为第i个子段的元素所得到的前i个子段和的最大值 ...
- 用python实现最长公共子序列算法(找到所有最长公共子串)
软件安全的一个小实验,正好复习一下LCS的写法. 实现LCS的算法和算法导论上的方式基本一致,都是先建好两个表,一个存储在(i,j)处当前最长公共子序列长度,另一个存储在(i,j)处的回溯方向. 相对 ...
- codevs 1576 最长上升子序列的线段树优化
题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...
- [LeetCode] Arithmetic Slices II - Subsequence 算数切片之二 - 子序列
A sequence of numbers is called arithmetic if it consists of at least three elements and if the diff ...
- [LeetCode] Is Subsequence 是子序列
Given a string s and a string t, check if s is subsequence of t. You may assume that there is only l ...
- [LeetCode] Wiggle Subsequence 摆动子序列
A sequence of numbers is called a wiggle sequence if the differences between successive numbers stri ...
- [LeetCode] Increasing Triplet Subsequence 递增的三元子序列
Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the ar ...
- [LeetCode] Distinct Subsequences 不同的子序列
Given a string S and a string T, count the number of distinct subsequences of T in S. A subsequence ...
- 动态规划之最长公共子序列(LCS)
转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...
随机推荐
- 部分rpm包总结描述
acl-2.2.51-15.el7.x86_64 Commands for Manipulating POSIX(可移植操作系统接口 of unix) Access Control Lists.有ge ...
- Python学习笔记 CH1-4:从入门到列表
Python CH1 环境准备 因为已经有了C/C++.Java的基础,所以上手很快. 参考书:Eric Matthes -<Python编程 从入门到实践> 环境准备:python3.P ...
- 一款检测代码中TODO的eslint插件
一款检测代码中TODO的eslint插件 前言 看了我标题进来的同学应该也知道我做的是个啥东西 没错是一个eslint插件,前端魔法师们日常所使用的工具之一 什么?你不知道eslint是干嘛的--吃鲸 ...
- 浅析MyBatis(四):全自动写代码的MyBatis逆向工程
在前面几篇文章中,笔者介绍了 MyBatis 的运行流程,在此基础上简单介绍了手写 MyBatis 简易框架与自定义 MyBatis 插件的步骤,相信大家对于 MyBatis 框架的使用流程已经游刃有 ...
- 从两个模型带你了解DAOS 分布式异步对象存储
摘要:分布式异步对象存储 (DAOS) 是一个开源的对象存储系统,专为大规模分布式非易失性内存 (NVM, Non-Volatile Memory) 设计,利用了 SCM(Storage-Class ...
- Android学习之活动的最佳实践
•问题的起源 先来模拟一个场景:打开一个 App,最先映入眼帘的是主活动(MainActivity),在该活动中给用户提供了一个 Button, 用户点击该 Button 实现由 MainActivi ...
- docker部署nodejs项目应用
之前笔者弄了一套nestjs项目放在自己服务器上,并用pm2管理进程. 现在要把pm2停止,尝试一下用docker容器,那么首先要安装docker 一.安装docker 由于笔者服务器的系统是cent ...
- 当初自学C++时的笔记记录
编辑:刘风琛 最初编写日期:2020年4月11日下午 最新更新日期:2020年9月20日上午 标注: 从笔记开始截止到程序第四章"程序流程结构",使用Joplin编写,其余部分为T ...
- Python数据分析入门(十七):绘制条形图
条形图的绘制方式跟折线图非常的类似,只不过是换成了plt.bar方法.plt.bar方法有以下常用参数: x:一个数组或者列表,代表需要绘制的条形图的x轴的坐标点. height:一个数组或者列表,代 ...
- ubuntu apt出错
whitedream@ubuntu:~$ sudo apt-get update Reading package lists... Done E: Could not get lock /var/li ...