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.
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).
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.
从数组的第一个数开始遍历直到遇到的第一个负数并记录第一个数的位置,如果前面所有正数与该负数之和小于0则记录该负数前一个数的位置并记录前面所有正数之和;继续从该负数的下一个数遍历下去;
从数组的第一个数开始记录此时的start的位置,每加一个数就记录此时的和并并记录成最大值,若是此时的和大于前面记录的最大值则将此时的start记录成最终的strat,将此时的end记录成最终的end;如果sum一直减小最终成了负数则抛弃此时的子数列,并从下一个数开始重复前面的步骤。(此思路可去尝试一番看能不能AC)
#include <iostream>
#define Max 100001
using namespace std;
long long int hanshu(int *a,int n,int *start,int *end)
{
int start1,end1;
long long int sum=0,max_sum=-1000;
*start=0;
for(int i=0;i<n;i++)
{
if(sum<0)
{
start1=i;
sum=a[i];
}
else
sum+=a[i];
if(max_sum<sum)
{
max_sum=sum;
*start=start1;
*end=i;
}
}
return (max_sum);
}
int main(void)
{
freopen("in.txt","r",stdin);
int N,a[Max],start,end,j=0;
long long int sum;
cin>>N;
while(N--)
{
j++;
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
start=0;
end=0;
sum=hanshu(a,n,&start,&end);
cout<<"Case "<<j<<":"<<endl;
cout<<sum<<" "<<start+1<<" "<<end+1<<endl;
if(N!=0)
cout<<endl;
}
fclose(stdin);
return 0;
}
此题总结:
就我个人而言,我认为此题是一道贪心思想题;我在最开始时也是直接从全局上进行考虑但思路到了中途就不能够继续推到下去了。而用贪心算法,即不断地去寻找局部的最优解,一步一步地进所有情况推导出,最终用代码来实现。
就此题而言,要想到用一个函数去解决问题,用指针去传递数值,定义一个新的变量去储存start和end,遇到max_sum在将他们赋值给真正的start与end。