题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003

Problem Description
Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14.
Input
The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line starts with a number N(1<=N<=100000), then N integers followed(all the integers are between -1000 and 1000).
Output
For each test case, you should output two lines. The first line is "Case #:", # means the number of the test case. The second line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the first one. Output a blank line between two cases.
Sample Input
2 5 6 -1 5 4 -7 7 0 6 -1 1 -6 7 -5
Sample Output
Case 1: 14 1 4Case 2: 7 1 6

思路一: 刚开始的第一反应就是枚举,枚举一个开头位置i,一个结尾位置j>=i,再求a[i..j]之间所有数的和,找出最大的就可以啦。当然代价也是很高的O(N^3)。

如下代码:

for(int i = 1; i <= n; i++){for(int j = i; j <= n; j++){int sum = 0;for(int k = i; k <= j; k++)sum += a[k];  max = Max(max, sum);}
}

思路二: 我们发现a[i..j]的和不是a[i..j – 1]的和加上a[j]么?所以我们在这里当j增加1的时候把a[j]加到之前的结果上不就可以了么?对!所以我们毫不费力地降低了复杂度,得到了一个新地时间复杂度为O(n^2)的更快的算法。
代码如下:

for(int i = 1; i <= n; i++){int sum = 0;for(int j = i; j <= n; j++){sum += a[j];max = Max(max, sum);}
}

思路三:

动态规划大显身手。我们记录dp[i]表示以a[i]结尾的全部子段中最大的和。我们看一下刚才想到的,我取不取a[i – 1],如果取a[i – 1]则一定是取以a[i – 1]结尾的子段和中最大的一个,所以是dp[i – 1]。 那如果不取dp[i – 1]呢?那么我就只取a[i]孤零零一个好了。注意dp[i]的定义要么一定取a[i]。 那么我要么取a[i – 1]要么不取a[i -1]。 那么那种情况对dp[i]有利? 显然取最大的嘛。所以我们有dp[i] = max(dp[i – 1]+ a[i], a[i]) 其实它和dp[i] = max(dp[i – 1] , 0) + a[i]是一样的,意思是说之前能取到的最大和是正的我就要,否则我就不要!初值是什么?初值是dp[1] = a[1],因为前面没的选了。

这样,我们的时间复杂度是O(n),空间复杂度也是O(n)——因为要记录dp这个数组。我们注意到dp[i] = max(dp[i - 1], 0) + a[i],看它只和dp[i – 1]有关,我们为什么要把它全记录下来呢?为了求所有dp[i]的最大值?不,最大值我们也可以求一个比较一个嘛。

我们定义endmax表示以当前元素结尾的最大子段和,当加入a[i]时,我们有endmax’ = max(endmax, 0) + a[i],然后再顺便记录一下最大值就好了。

老生常谈的问题来了。我们如何找到一个这样的子段?请看伪代码endmax = max(endmax, 0) + a[i], 对于endmax它对应的子段的结尾显然是a[i],我们怎么知道这个子段的开头呢? 就看它有没有被更新。也就是说如果endmax’= endmax + a[i]则对应子段的开头就是之前的子段的开头。否则,显然endmax开头和结尾都是a[i]了。说到这里是不是已经明了呢?那就看看具体的代码吧。

代码如下:

for(int i=1; i<=n; i++){  if(b>0)b+=a[i];  elseb=a[i];  if(b>sum)sum=b;  //sum=max(b,sum);}  

下面就此题贴出完整代码:

#include<iostream>
#define M 5000+5
#define LL long long
#include<cstring>
using namespace std;  LL MaxSum(int n,int a[]){  LL sum=0;  int b=0;  for(int i=1; i<=n; i++){  if(b>0)b+=a[i];  elseb=a[i];  if(b>sum)sum=b;  //sum=max(b,sum);}
return sum;
}
int main(){  int n,a[M],m;LL maxsum;  while(cin>>n){for(m=0; m<n; m++)  cin>>a[m];  int b[M];  for(m=0; m<n; m++)  b[m+1]=a[m];  maxsum=MaxSum(n,b);  cout<<maxsum<<endl;  }return 0;
}

HD 1003 Max Sum (最大字段和问题)相关推荐

  1. HD 1003 Max Sum(贪心)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003 Problem Description Given a sequence a[1],a[2],a ...

  2. hdu 1003 Max Sum (DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003 Max Sum Time Limit: 2000/1000 MS (Java/Others)   ...

  3. HDU.1003 Max Sum

    原题 HDU.1003 Max Sum 分类 动态规划 题意 计算从一个序列中最大连续子序列和.对应的起始元素和终止元素的位置. 输入/输出 要求与格式 样例数的确定 最开始一行开始输入样例数 每个样 ...

  4. 杭电OJ——ACM 1003.Max Sum

    Max Sum 杭电OJ--ACM 1003.Max Sum链接入口 问题描述 大意:        给定一个序列a[1],a[2],a[3]-a[n],你需要算出其子序列中的最大值.比如说:给你一个 ...

  5. hdu 1003 Max Sum 解题报告

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003 Problem Description Given a sequence a[1],a[2],a[3 ...

  6. hdu 1003 Max Sum

    DP可以这里给出非DP程序 题目传送门 1 #include<stdio.h> 2 int main() 3 { 4 int t,n,i,max,m,sum,ki,kj,k,a,b; 5 ...

  7. [hdu 1003] Max Sum

    跟<算法导论(第三版)>上的一样,抄下来的 30 - 60 ms 标准的分治策略 1 #include <stdio.h> 2 3 int A[100000], Lenght; ...

  8. HDU 1003——Max Sum(动态规划)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003 题目大意:历遍所有数字,找出最大字段和. 解题思路: t和n:记录循环次数和每一段有多少个数字 ...

  9. 位置子段最大子段和 hdu 1003 max sum ACM的开始

    每日一贴,今天的内容关键字为位置子段 这个标题的印象是较比刻深的,我的第一个动态规划标题,也是ACM的开始.最大字段和是较比经典的动归问题.求一个列序的最大子段和的关键点就在于断判一个元素的归属问题, ...

最新文章

  1. MATLAB中的vpa函数简单实用记录——精度控制
  2. 普通用户程序使用保留端口 error while loading shared libraries
  3. POJ2104 K-th Number [分块做法]
  4. mysql---视图
  5. React  学习第二天 2018-07-21
  6. ArrayBlockingQueue原理分析-remove方法
  7. CGI(通用网关接口)
  8. java开源播放器_JavaFX/Java8开发的开源音乐播放器
  9. Linux内核精选文章向读者汇报 | 相遇Linux
  10. 二维数组,字符串,字符数组
  11. 读书篇:《细说PHP》三、PHP的语言结构
  12. PMP培训机构哪家好,求推荐?
  13. java验证码实现简单_简单实现Java验证码功能
  14. 从Simulink到PX4——Simulink-PX4插件安装与环境搭建
  15. Redis学习之lpush命令
  16. Easyui文件上传格式限制
  17. 寒假每日一题——贝茜放慢脚步
  18. I3D【Inflated 3D ConvNet】——膨胀卷积网络用于行为识别
  19. 时间计算题100道_数学大作战!小学13000道计算题+20000道口算题立即领!
  20. 图片批量转换成pdf

热门文章

  1. 金融系列白皮书 |《金融业线上渠道转型的方法与实践》上线
  2. 如何成为一名大数据工程师?
  3. 如何学习配置webpack(一)
  4. 微信内测附近的餐厅,小程序要跨界外卖了?
  5. 【2018年11月21日】煤炭行业的估值高度排名
  6. Qt之QSlider
  7. 不区分大小写的内容比较
  8. c#接口和抽象类的区别
  9. pthread属性使用(转)
  10. Linux chmod 命令 详解