Max Sum Plus Plus

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 44371    Accepted Submission(s): 16084

Problem Description

Now I think you have got an AC in Ignatius.L's "Max Sum" problem. To be a brave ACMer, we always challenge ourselves to more difficult problems. Now you are faced with a more difficult problem.

Given a consecutive number sequence S1, S2, S3, S4 ... Sx, ... Sn (1 ≤ x ≤ n ≤ 1,000,000, -32768 ≤ Sx ≤ 32767). We define a function sum(i, j) = Si + ... + Sj (1 ≤ i ≤ j ≤ n).

Now given an integer m (m > 0), your task is to find m pairs of i and j which make sum(i1, j1) + sum(i2, j2) + sum(i3, j3) + ... + sum(im, jm) maximal (ix ≤ iy ≤ jx or ix ≤ jy ≤ jx is not allowed).

But
I`m lazy, I don't want to write a special-judge module, so you don't
have to output m pairs of i and j, just output the maximal summation of
sum(ix, jx)(1 ≤ x ≤ m) instead. ^_^



Input

Each test case will begin with two integers m and n, followed by n integers S1, S2, S3 ... Sn.
Process to the end of file.



Output

Output the maximal summation described above in one line.



Sample Input

  -  -  - 

Sample Output


题目大意

从一序列中取出若干段,这些段之间不能交叉,使得和最大并输出。、

题目分析

动态规划 首先我们可以列出最基本的状态转移方程:

    dp[i][j] = max( dp[i][j-1] + a[j] , dp[i-1][k] + a[j ])    i-1<=k<=j-1

    这个方程的含义是:

        dp[i][j] 是将前 j 个数分成 i 份,且第 i 份包含第 j 个数 的情况下的最大值

        那么对于第 j 个数来说,就有两个选择:

              作为第 i 份的一部分 :也就是将前 j-1 个数分成 i 份 且第 j-1 个数属于第 i 份 即 dp[i][j-1]

              或者单独出来成为第 i 份:也就是将前 j-1 个数分成 i-1 份 且第 j-1 个数不一定属于第 i-1 份  即 dp[i-1][k] i-1<=k<=j-1

但是这个方程不仅时间复杂度高,空间复杂度也高的可怕 这是不行的

所以我们要将其优化:

首先我们发现 dp[i][j] 只需要比较 dp[i][j-1] 与 dp[i-1][k] 的最大值即可 而这个 dp[i-1][k] 的最大值是可以记录下来的 不需要遍历 这就砍去了一层循环

    所以我们只需要定义一个 pre[n] 数组 用 pre[j] 来存储第 j-1 个数被分成 i-1 份时的最大值即可

    于此同时 在计算 dp[i][j] 时,我们可以计算出 dp[i][k] i<=k<=j 的值 而这个值是在之后我们要计算 dp[i+1][j+1] 时 要使用的 pre[j]

现在状态转移方程变成了:
    dp[i][j] = max( dp[i][j-1] + a[j] , pre[j-1] + a[j ])

现在我们发现 由于pre[j] 的存在 似乎已经不需要 dp[i][j] 这个庞大的二维数组了 只需要开一个 dp[n] 的数组 用dp[j]来存储dp[i][j]即可,因为当前的转移方程根本就没有用到 i 这一维!

这样的话 转移方程又变成了:
    dp[j] = max( dp[j-1] + a[j] , pre[j-1] + a[j ])

不过 i 的这一层循环还是得循环的 这个砍不掉的...

#include<bits/stdc++.h>

using namespace std;

int n,m,dp[],a[],pre[],i,j,temp;

int main()
{
while(scanf("%d %d",&m,&n)!=EOF)
{
memset(dp,,sizeof(dp));
memset(a,,sizeof(a));
memset(pre,,sizeof(pre));
for(i=;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(i=;i<=m;i++)
{
temp=-0x7ffffff;
for(j=i;j<=n;j++)
{
dp[j]=max(dp[j-],pre[j-])+a[j];
pre[j-]=temp;
temp=max(temp,dp[j]);
}
}
cout<<temp<<endl;
}
}

HDU 1024 Max Sum Plus Plus (动态规划、最大m子段和)的更多相关文章

  1. 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/ ...

  2. HDU 1024 Max Sum Plus Plus [动态规划+m子段和的最大值]

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

  3. hdu 1024 Max Sum Plus Plus (动态规划)

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

  4. HDU 1024 Max Sum Plus Plus (动态规划 最大M字段和)

    Problem Description Now I think you have got an AC in Ignatius.L's "Max Sum" problem. To b ...

  5. HDU - 1024 Max Sum Plus Plus 最大m段子段和+滚动数组优化

    给定n个数字,求其中m段的最大值(段与段之间不用连续,但是一段中要连续) 例如:2 5 1 -2 2 3 -1五个数字中选2个,选择1和2 3这两段. dp[i][j]从前j个数字中选择i段,然后根据 ...

  6. 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 ...

  7. HDU 1024 Max Sum Plus Plus --- dp+滚动数组

    HDU 1024 题目大意:给定m和n以及n个数,求n个数的m个连续子系列的最大值,要求子序列不想交. 解题思路:<1>动态规划,定义状态dp[i][j]表示序列前j个数的i段子序列的值, ...

  8. 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 ...

  9. HDU 1024 max sum plus

    A - Max Sum Plus Plus Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I6 ...

随机推荐

  1. cursor(鼠标手型)属性

    ㈠简单介绍 在浏览网页时,通常看到的鼠标光标形状有箭头.手形.沙漏等,而在 windows 中实际看到的鼠标指针种类比这个还要多. 一般情况下,鼠标光标的形状由浏览器负责控制,大多数情况的光标形状为箭 ...

  2. Python 创建数据库表

    创建数据库表 如果数据库连接存在我们可以使用execute()方法来为数据库创建表,如下所示创建表EMPLOYEE: #!/usr/bin/python # -*- coding: UTF-8 -*- ...

  3. HTML+CSS知识总结1

    一.浏览器页面页面由结构层(html)表现层(css)行为层(js)组成 二.DOCTYPE作用是用来告知浏览器以何种模式渲染文档. 三.严格模式是指浏览器按照W3C标准解析代码,混杂模式又称怪异模式 ...

  4. SpringBoot项目中,AOP的使用

    Springboot中自带依赖 1.创建一个SellerAuthorizeAspect类,打上标签@Aspect和@Component @Aspect @Component @Slf4j public ...

  5. MessagePack Java 0.6.X 使用一个消息打包(message-packable)类

    使用注解 @Message 来让你可以序列化你自己类中对象的 public 字段. 本代码可以在 https://github.com/cwiki-us-demo/messagepack-6-demo ...

  6. 如何运行一个分布式的Maven项目

    本人也属于一个新手小白,之前在公司运行的项目也都不涉及到maven...但是前两天运行一个maven项目的时候发现,第一次接触这个还是蛮让我措手不及的.在这里整理下自己当时走的弯路,或者遇到的一些问题 ...

  7. 自动化部署脚本之windows上执行批处理文件

    windows  .bat  批处理 脚本路径如下: install-simo.bat文件内容: @ECHO OFF set scriptpath=%~dp0set logfile=%scriptpa ...

  8. 链表栈C语言实现

    #ifndef LINKSTACK_H_INCLUDED #define LINKSTACK_H_INCLUDED #include <stdlib.h> #include <std ...

  9. charts_03

    table 数值获取: 1.http://www.w3school.com.cn/jsref/dom_obj_all.asp 2.http://blog.csdn.net/xs_zgsc/articl ...

  10. SQLite 数据类型与C#数据类型对应表

        SQLite 数据类型 C# 数据类型   BIGINT Int64   BIGUINT UInt64   BINARY Binary   BIT Boolean 首选 BLOB Binary ...