DP动态规划--最大子段和--Max Sum

来源:互联网 发布:张伯伦个赛季数据统计 编辑:程序博客网 时间:2024/06/10 19:36

Description

Given a sequencea[1],a[2],a[3]......a[n], your job is to calculate the max sum of asub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is6 + (-1) + 5 + 4 = 14. 

 

Input

The first lineof the input contains an integer T(1<=T<=20) which means the number oftest cases. Then T lines follow, each line starts with a numberN(1<=N<=100000), then N integers followed(all the integers are between-1000 and 1000). 

 

Output

For each testcase, you should output two lines. The first line is "Case #:", #means the number of the test case. The second line contains three integers, theMax Sum in the sequence, the start position of the sub-sequence, the endposition of the sub-sequence. If there are more than one result, output thefirst 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

 

 动态转移方程:s[i]=max(s[i-1]+a[i],a[i])

详细注释看代码

#include<stdio.h>#include<algorithm>#include<iostream>using namespace std;int main(){int t,k;cin>>t;while(t--){int n,i,j;cin>>n;int a[100005]={0};int s[100005]={0}; //s数组记录到 !当前位置! 的最大子段和 int mx=-0x3fffffff;int t1,t2;//记录最大子段和的起点和终点 for(i=1;i<=n;i++){cin>>a[i];s[i]=max(s[i-1]+a[i],a[i]);//更新s[i]//若 s[i-1]+a[i]> a[i],则当前位置的最大子段和为前一位置的最大子段和加上a[i]if(mx<s[i])//查找最大的s[i] {mx=s[i];//更新最大值 t2=i;//更新终点 } }for(i=t2;i>0;i--){if(s[i]==a[i]&&s[i-1]!=0)//s[i]==a[i]代表当前位置的子段和不是由前边的子段和继承过来的,所以是起点//s[i-1]!=0是防止类似5,-5,1,2,-1,4这种情况的出现,若不加此条件,则起点会被更新为从1的位置开始,而不是从5的位置开始 {t1=i;break;}}if(i==0)//到头没找到,初始位置为1; t1=1;printf("Case %d:\n%d %d %d\n",k,mx,t1,t2);if(t>0)printf("\n");k++;}} 

原创粉丝点击