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
Author
Ignatius.L
以前在算法书上当;例题解过,思想倒是记住了,但是实现的时候还是WA了好几次
思路:定义结构体保存区间状态max保存最优解的状态,temp为动态区间它保存从le到ri的所有数字的和,当这个和大于max状态的和时,将temp赋给max将最优解保存下来,当temp的sum小于0时,给它赋值0并将区间移到当前位置,然后继续往下走
看代码吧:
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<list>
#include<iterator>
#include<stack>
#include <queue>
#include <cstdio>
//#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define e 2.718281828459
#define INF 0x7fffffff
#pragma warning(disable:4996)
#define sf scanf
#define pf printf
#define sf2d(x,y) scanf("%d %d",&(x),&(y))
#define sfd(x) scanf("%d",&x)
#define sff(p) scanf("%lf",&p)
#define pfd(x) printf("%d\n",x)
#define mset(x,b) memset((x),b,sizeof(x))
const double pi = acos(-1.0);
const long long mod = 1000000007LL;
int a[100002];
struct node {
int le,ri;//区间左右端点
ll sum;//和
node():le(0),ri(0),sum(0){
}
bool operator>=(node& a) {
return sum >= a.sum;
}
};
int main(void){
int t, n;
sfd(t);
for(int m=1; m<=t ; m++){
node max, temp;
sfd(n);
for (int i = 0; i < n; i++)
sfd(a[i]);
max.sum = -1001;//初始化为最小值
for (int i = 0; i < n; i++) {
temp.sum += a[i];//更新temp的sum
temp.ri = i;//更新区间右端点
if (temp >= max) {//保存最优解
max = temp;
}
if (temp.sum < 0) {//当temp.max<0时说明当前这个区间绝对不会是最优解(最大子序列和肯定大于0的),此时将区间更新到以当前位置为左端点的区间状态
temp.ri = temp.le = i+1;
temp.sum = 0;
}
}
pf("Case %d:\n", m);
//注意下打印的格式
if (m < t)
pf("%lld %d %d\n\n", max.sum,max.le+1, max.ri+1);
else
pf("%lld %d %d\n", max.sum, max.le + 1, max.ri + 1);
}
return 0;
}