给你一段包含负数的序列,问你这段序列的最大和是多少?并且打印出最大和区间?例如假设有两个序列如下:
5: 6 -1 5 4 -7
7: 0 6 -1 1 -6 7 -5
很容易看出第一个包含5个元素的序列的最大和是14.区间从1到4.第二个最大和是7,区间可以有两个,从1到6或则从6到6.
这是DP的一个经典问题,我们用sum来表示从tp到i的和,max表示从st到ed的最大和,算法就是从头开始遍历序列,每次都令sum+=a[i].判断当前sum是否大于已经得到的max。若是,则更新max和最大值区间。再判断sum是否小于0,若是,则重新令sum=0;并且更新tp的值。
代码如下:
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 #define INF 0x3f3f3f3f 5 6 int main() 7 { 8 int n, t, a, lp=1; 9 scanf("%d", &t); 10 while(t--) 11 { 12 scanf("%d", &n); 13 int st, ed, tp=1; 14 __int64 sum=0, max = -INF; 15 16 for(int i=1; i<=n; i++) 17 { 18 scanf("%d", &a); 19 sum += a; 20 if(sum > max) 21 { 22 max = sum; 23 st = tp; 24 ed = i; 25 } 26 if(sum < 0) 27 { 28 sum = 0; 29 tp = i+1; 30 } 31 } 32 printf("Case %d: %I64d %d %d ",lp++, max, st, ed); 33 if(t) printf(" "); 34 } 35 return 0; 36 }