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. Activiti使用

    Activiti是一个开源的工作流引擎,它实现了BPMN 2.0规范,可以发布设计好的流程定义,并通过api进行流程调度. Activiti 作为一个遵从 Apache 许可的工作流和业务流程管理开源 ...

  2. Python 异常处理Ⅲ

    使用except而不带任何异常类型 你可以不带任何异常类型使用except,如下实例: 以上方式try-except语句捕获所有发生的异常.但这不是一个很好的方式,我们不能通过该程序识别出具体的异常信 ...

  3. C# 扩展方法——去重(Distinct)

    其他扩展方法详见:https://www.cnblogs.com/zhuanjiao/p/12060937.html IEnumerable的Distinct扩展方法,当集合元素为对象时,可用于元素对 ...

  4. jquery focus()方法 语法

    jquery focus()方法 语法 作用:当元素获得焦点时,发生 focus 事件.大理石平台价格 触发focus事件语法:$(selector).focus() 将函数绑定到focus事件语法: ...

  5. jquery input选择器 语法

    jquery input选择器 语法 作用::input 选择器选取表单元素.该选择器同样适用于 <button> 元素.大理石平台价格表 语法:$(":input") ...

  6. Redis 集群规范

    什么是 Redis 集群??Redis 集群是一个分布式(distributed).容错(fault-tolerant)的 Redis 实现,集群可以使用的功能是普通单机 Redis 所能使用的功能的 ...

  7. ubuntu下jps命令无效

    jps命令无效 #启动zookeeper $ sudo ./zkServer.sh start [sudo] jjboom 的密码: ZooKeeper JMX enabled by default ...

  8. (转译)2019年WEB漏洞扫描工具和软件前十名推荐

    这些工具都有助于发现漏洞,从而最大限度地提高测试人员的时间和效率.这些工具,2019年更新,也可用于寻找漏洞. 为何扫描? 这资源是什么? Web应用程序对黑客具有极大的吸引力,并且出于百万种不同的原 ...

  9. 【学习】mysql 时间戳与日期格式的相互转换

    1.UNIX时间戳转换为日期用函数: FROM_UNIXTIME() ); 输出:2006-08-22 12:11:10 2.日期转换为UNIX时间戳用函数: UNIX_TIMESTAMP() Sel ...

  10. SpringBoot 使用定时任务动态执行任务

    import com.patient.core.adapter.CorsFilter; import org.mybatis.spring.annotation.MapperScan; import ...