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. ng-reapte指令遍历

    <!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta cha ...

  2. IE8 浏览器文本模式变为杂项(quirks)页面变形的解决方法

    IE8 浏览器文本模式(document.documentMode)变为杂项(quirks)页面变形的解决方法. 正常情况下 document.documentMode 输出为8,而变为杂项之后doc ...

  3. 手动升级 Confluence - 规划你的升级

    1. 确定你的升级路径 使用下面的表格来确定最佳的升级路径来让你的Confluence 从当前版本升级到最新的 Confluence 版本. 你的版本 推荐升级到 Confluence 的升级路径 2 ...

  4. JavaWeb_客户端相对/绝对路径和服务器端路径

    客户端的绝对路径和相对路径 相对路径:相对与某个基准目录的路径,在同一根目录下各子目录文件之间的相互引用, 绝对路径:指目录下的绝对位置,直接到的目标位置 @charset "UTF-8&q ...

  5. RESTful API Design

    https://restful-api-design.readthedocs.org/en/latest/scope.html http://blog.mashape.com/30-ways-to-m ...

  6. C++入门经典-例5.10-指针作为返回值

    1:代码如下: // 5.10.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> usin ...

  7. _parameter:解决There is no getter for property named in class java.lang.String

    我们知道在mybatis的映射中传参数,只能传入一个.通过#{参数名} 即可获取传入的值. Mapper接口文件: public int delete(int id) throws Exception ...

  8. 使用 sed 命令查找和替换文件中的字符串的 16 个示例

    当你在使用文本文件时,很可能需要查找和替换文件中的字符串.sed 命令主要用于替换一个文件中的文本.在 Linux 中这可以通过使用 sed 命令和 awk 命令来完成. 在本教程中,我们将告诉你使用 ...

  9. Use an Excel RTD Server with DCOM

    费好大劲找到的文章,留存. Use an Excel RTD Server with DCOM 如何使用DCOM的Excel RTD服务器 Microsoft Office Excel 2007,Mi ...

  10. Javadoc常见的标记和含义

    1.@param 方法参数的说明 2.@return 对 方法返回值的说明 3.@throws 方法抛出异常的描述 4.@version模块的版本号 5.see参数转向 6.@deprecated标记 ...