注:摘的老师写的

最大m子段和问题

以-1 4 -2 3 -2 3为例
最大子段和是:6
最大2子段和是:4+(3-2+3)=8
所以,最大子段和和最大m子段和不一样,不能用比如先求一个最大子段和,从序列中去掉已求子段,再求下一个最大子段和的方法,这种方法有点贪心的味道,但是不行。所以,还得用动态规划。

1.基本思路:
  首先,定义数组num[n],dp[m][n]. 
  num[n]用来存储n个整数组成的序列. dp[m][n]代表n个整数序列求m个子段和。

按照分阶段的思想,我们首先考虑最后一项,即num[n].num[n]属于最大m子段和只有两种情况,

如果用搜索树表示的话,只有两个分支,

一个是属于最大m子段和(肯定是第m子段),

另一个是不属于(即最大m子段和在前n-1个整数中构成)。
  先说属于情况,即第m子段由num[n]结尾,又分两种情况:要么自己独立成一个子段,要么与前边以num[j-1]结尾的子段联合。所以,我们用b[m][n]表示最后一个子段以num[n]项结尾的最大m子段和。则
b[m][n]=max{b[m][n-1]+num[n],b[m-1][t]+num[n]},其中后一项表示num[n]自己成一段,前面t个整数(以每个整数为子段最后一项)(1<=t<=n-1)。
  再说不属于情况,则dp[m][n]=dp[m][n-1],表示由n-1个整数构成m个子段和最大。(不包括num[n])
  综合这两种情况:
  dp[m][n]=max{b[m][n-1]+num[n],b[m-1][t]+num[n],dp[m][n-1]}
  推广一下:
  dp[i][j]=max{b[i][j],dp[m][n-1]}=max{b[i][j-1]+num[j],b[i-1][t]+num[j],dp[i][j-1]}
  dp[0][1]=dp[1][0]=0
  b[0][1]=b[1][0]=0
  
  以下,验证一下:
  以4 -2 3 -2 3为例
  dp[1][1]=max{b[1][0]+4,b[0][0]+4,0}=4  b[1][1]=4
  dp[1][2]=max{b[1][1]-2,(b[0][0],b[0][1])+4,dp[1][1]}=4    b[1][2]=4-2=2
  dp[1][3]=max{b[1][2]+3,(b[0][0],b[0][1],b[0][2])+4,dp[1][2]}=max{5,4,4}=5   b[1][3]=5
  dp[1][4]=max{b[1][3]-2,(b[0][0],b[0][1],b[0][2],b[0][3])+4,dp[1][3]}=max{3,4,5}=5  b[1][4]=3
  dp[1][5]=max{b[1][4]+3,(b[0][0],b[0][1],b[0][2],b[0][3],b[0][4])+4,dp[1][4]}=max{6,4,5}=6  b[1][5]=6

dp[2][1]=0  b[2][1]=0
  dp[2][2]=max{b[2][1]-2,(b[1][0],b[1][1])-2,dp[2][1]}=max{-2,2,0}=2  b[2][2]=2
  dp[2][3]=max{b[2][2]+3,(b[1][0],b[1][1],b[1][2])+3,dp[2][2]}=max{5,7,2}=7  b[2][3]=7
  dp[2][4]=max{b[2][3]-2,(b[1][0],b[1][1],b[1][2],b[1][3])-2,dp[2][3]}=max{5,3,7}=7  b[2][4]=5
  dp[2][5]=max{b[2][4]+3,(b[1][0],b[1][1],b[1][2],b[1][3],b[1][4])+3,dp[2][4]}=max{8,8,7}=8  b[2][5]=8
  
  验证表明,分析正确。

但是,我们会发现,当n非常大时,这个算法的时间复杂度和空间复杂度是非常高的,时间复杂度近似为O(m*n^2),
  空间复杂度近似为O(m*n).因此,我们需要优化算法来降低时间复杂度和空间复杂度.

 #include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int curr[],pre[],arr[];
const int MAX = -;
int sum = ;
int main()
{
int m,n;
while(cin>>m>>n)
{
memset(curr,,sizeof(curr));
memset(pre,,sizeof(pre));
for(int i=;i<=n;i++)
cin>>arr[i];
int j=;
for(int i=;i<=m;i++)
{
sum = MAX;
for(j=i;j<=n;j++)
{
curr[j] = max(curr[j-],pre[j-])+arr[j];
pre[j-] = sum;
sum = max(sum,curr[j]);
}
pre[j-] = sum; }
cout<<sum<<endl;
}
}

hdu 1024 最大m子段和的更多相关文章

  1. hdu 1024 最大M子段dp

    题目: Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Ot ...

  2. HDU 1024 max sum plus

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

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

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

  4. 怒刷DP之 HDU 1024

    Max Sum Plus Plus Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  5. Max Sum Plus Plus HDU - 1024

    Max Sum Plus Plus     HDU - 1024 Now I think you have got an AC in Ignatius.L's "Max Sum" ...

  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【动态规划求最大M子段和详解 】

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

  8. (最大m子段和) Max Sum Plus Plus (Hdu 1024)

    http://acm.hdu.edu.cn/showproblem.php?pid=1024     Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/ ...

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

随机推荐

  1. No mapping found for HTTP request with URI [/spring_liu/hello.do] in DispatcherServlet with name 'SpringMVC'

    控制台一直报No mapping found for HTTP request with URI [/spring_liu/hello.do] in DispatcherServlet with na ...

  2. vue-cli 打包 使用 history模式 的后端配置

    apache的配置 这是windows下的 在httpd-vhosts.conf文件中把目录指向项目index.html文件所在的位置 # Virtual Hosts # <VirtualHos ...

  3. Linux shell 内部变量

    1 TMOUT 来自bash的解释: If set to a value greater than zero, TMOUT is treated as the default timeout for ...

  4. spring中操作mysql数据库

    就是在spring中,对mysql数据库进行增删改查的样例,很easy. 文件结构 maven的pom.xml文件,里面用到的几个很重要的jar包都有 <project xmlns=" ...

  5. 聊聊高并发(四十四)解析java.util.concurrent各个组件(二十) Executors工厂类

    Executor框架为了更方便使用,提供了Executors这个工厂类.通过一系列的静态工厂方法.能够高速地创建对应的Executor实例. 仅仅有一个nThreads參数的newFixedThrea ...

  6. _00020 妳那伊抹微笑_谁的异常最诡异第一期之 SqlServer RSA premaster secret error

    博文作者:妳那伊抹微笑 博客地址:http://blog.csdn.net/u012185296 博文标题:_00020 妳那伊抹微笑_谁的异常最诡异第一期之 SqlServer RSA premas ...

  7. 图文介绍MyEclipse (2015) 中创建简单的Maven项目的步骤(用于生成可运行jar文件)

    利用MyEclipse的引导,能够非常方便的创建简单的.用于生成可运行jar文件的Maven项目: (原创文章,转载请注明转自Clement-Xu的博客:http://blog.csdn.net/cl ...

  8. 最快的方式清除Chrome浏览器DNS缓存

    最快的方式就是直接数据url,然后清除不须要的dns缓存. chrome://net-internals/#dns 一般步骤.要经过下列几项. Chrome - > 扳手 - > 选项 - ...

  9. node03--http

    form.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  10. 【转】webshell检测——使用auditd进行system调用审计

    本文档将介绍:如何通过Linux审计系统auditd监测WebShell执行系统命令的行为. 测试环境:CentOS7.0_x64 auditd简介 Linux审计系统提供了一种跟踪系统上与安全相关的 ...