题意:

     给你一个序列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子序列和的更多相关文章

  1. 最大m段子段和

    hdu1024 最大m子序列和 给定你一个序列,让你求取m个子段(不想交的子段)并求取这m个子段和的最大值 从二维开始来看dp[i][j]表示取第j个数作为第i个子段的元素所得到的前i个子段和的最大值 ...

  2. 用python实现最长公共子序列算法(找到所有最长公共子串)

    软件安全的一个小实验,正好复习一下LCS的写法. 实现LCS的算法和算法导论上的方式基本一致,都是先建好两个表,一个存储在(i,j)处当前最长公共子序列长度,另一个存储在(i,j)处的回溯方向. 相对 ...

  3. codevs 1576 最长上升子序列的线段树优化

    题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...

  4. [LeetCode] Arithmetic Slices II - Subsequence 算数切片之二 - 子序列

    A sequence of numbers is called arithmetic if it consists of at least three elements and if the diff ...

  5. [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 ...

  6. [LeetCode] Wiggle Subsequence 摆动子序列

    A sequence of numbers is called a wiggle sequence if the differences between successive numbers stri ...

  7. [LeetCode] Increasing Triplet Subsequence 递增的三元子序列

    Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the ar ...

  8. [LeetCode] Distinct Subsequences 不同的子序列

    Given a string S and a string T, count the number of distinct subsequences of T in S. A subsequence ...

  9. 动态规划之最长公共子序列(LCS)

    转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...

随机推荐

  1. Java练习——抽象类

    需求: 2辆宝马,1辆别克商务舱,1辆金龙(34)座,租5天共多少租金.   轿车 客车(金杯.金龙) 车型 别克商务舱GL8 宝马550i 别克林荫大道 <=16座 >16座 日租费(元 ...

  2. 167. 两数之和 II - 输入有序数组 + 哈希表 + 双指针

    167. 两数之和 II - 输入有序数组 LeetCode_167 题目描述 方法一:暴力法(使用哈希表) class Solution { public int[] twoSum(int[] nu ...

  3. LanQiao-297(快速排序)

    快速排序 LanQiao-297 #include<iostream> #include<cstdio> #include<algorithm> #include& ...

  4. xss靶场大通关(持续更新ing)

      xss秘籍第一式(常弹) (1)进入自己搭建的靶场,发现有get请求,参数为name,可进行输入,并会将输入的内容显示于网页页面 (2)使用xss的payload进行通关: http://127. ...

  5. web之面试常问问题:如何实现水平垂直居中?

    前提准备,在HTML页面中定义一个div,div中内容自定义. <div class="box sc">致我们呼啸而过的青春</div> 样式: div.b ...

  6. vue Element-ui el-menu 左侧导航条

    <template> <!--实现左侧导航条动态渲染(三级)--> <el-menu class="el-menu-vertical-demo" @o ...

  7. wireshark如何抓取分析https的加密报文

    [问题概述] https流量基于ssl/tls加密,无法直接对报文进行分析. [解决方案] 方案1 -- 利用"中间人攻击"的代理方式抓包分析.整个方案过程比较简单,这里不赘述,大 ...

  8. 计算机图形学中使用Turbo C++画图步骤

    一.下载安装Turbo C++ 我安装的是Turbo C++ 3.2.2.0下载链接 二.画图 1.打开Turbo C++,点击右下角start turbo C++ 2.点击file ->new ...

  9. matplotlib常规使用方法

    1,指定图片大小和像素 Python绘图问题:Matplotlib中指定图片大小和像素 2,绘图命令的基本架构及其属性设置 绘图与可视化 3,python基础语法(二)--- plt的一些函数使用 p ...

  10. vue封装公用弹出框方法,实现点击出现操作弹出框

    vue封装公用弹出框方法,实现点击出现操作弹出框 如上图所示,这次要实现一个点击出现操作弹框的效果:并将这个功能封装成一个函数,便于在项目的多个地方使用. 具体思路是: 封装一个组件,组件保护一个插槽 ...