题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1003
Max Sum
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 4 Case 2: 7 1 6
做这题的时候遇到的几个困难,本人菜鸟一个,所以高手请略过...
本题用到的算法:动态规划(最大子段和)
首先看下面代码,我标注出了在编程过程中遇到的四个问题:
#include<iostream>
using namespace std;
#define NUM 100001
int a[NUM];
int t=0;
int MaxSum(int n,int &besti,int &bestj)
{
int sum=-10000; //问题一
int b=0;
int begin=1; //问题二
for(int i=1;i<=n;i++)
{
if(b>=0) //问题三
b+=a[i];
else
{
b=a[i];
begin=i;
}
if(b>sum)
{
sum=b;
besti=begin;
bestj=i;
}
}
return sum;
}
int main()
{
int n;
scanf("%d",&n);
int c=0,b;
while(n--)
{
int m;
cin>>m;
b=m;
for(int i=1;i<=m;i++)
scanf("%d",&a[i]);
cout<<"Case "<<++t<<":"<<endl;
cout<<MaxSum(m,c,b)<<" "<<c<<" "<<b<<endl;
if(n>0) //问题四
cout<<endl;
}
}
问题一,开始我把sum赋初值为0,后来发现,如果最大子段和是负数怎么办?如果把sum赋初值为0,那么最大子段和最小为0
问题二,最大子段和可能是一个数,也可能是好几个数相加的和,所以定义begin这个变量就是用来记录最后所求的最大子段和的起点是从第几位开始的。比如:6 -1 5 4 -7 这里有5个数,最大子段和是14,是从第一个数6开始到第四个数4结束的,所以这里是从第一个数开始,所以定义begin=1。本人一开始赋初值为0,所以错了。
问题三,应该说我对这个算法还不是十分清楚,只能怪自己学习的时候不够认真,所以开始的时候我是很死板的按照书上的算法打下来的if(b>0) ,而如果这样,那么输出第二个数就不是1了,而是6,因为从第一个数到第五个数相加之后和刚好为0,那么此时begin就会改写为6(第6个数),这个也要注意。
问题四,这个问题很纠结,可能是因为我英文不好题目没看清楚。题目要求是每一组测试例之间要输出一空行,但是最后一行输出后不要空行,所以要加一个判断语句来判断是不是最后一组测试例,如果是,那么输出最后一个测试例的答案后就不要再空一行了。