题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003
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
分析:
这题就是求最大连续子序列,可以用dp状态递推式
ans[i]=max(ans[i-1]+a[i],a[i]);
其中ans[i]表示以第i个数为结尾的最大连续子序列,但是这种办法不方便记录左右端点。
可以直接枚举,以第i个数为左端点,不断向右推右端点j,当区间和加上右端点 j 上的数小于0,则重置左端为j+1。每次加上一个数都要与当前最大数比较,时间复杂度为O(n)
AC代码:
#include <iostream>
#include <cstdio>
using namespace std;
const int MAXN = 1e5+5;
int a[MAXN];
int main()
{
int T,Case=1;
cin >> T;
while( T--) {
int n;
cin >> n;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int ans=-0x3f3f3f,temp,l=0,r=0;
int j;
for(int i=1;i<=n;i=j+1) {
j=i;
if(a[i]<0) {
if(a[i] > ans) {
ans = a[i];
l = r = i;
}
continue;
}
temp = 0;
for(;j<=n;j++) {
if(temp+a[j] < 0)
break;
temp += a[j];
if(temp > ans) {
ans = temp;
l = i;
r = j;
}
}
}
printf("Case %d:\n%d %d %d\n",Case++,ans,l,r);
if( T!= 0)
cout << endl;
}
}