Max Sum
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
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
Case 2: 7 1 6
Answer
自己都不怎么理解,写起来费劲...写下来自己忘了可以看看...
题目是要求最大子串和,限时1s,如果枚举所有子串一定会超时,所以方法是动态规划。
当考虑以a[n]结尾的子串最大和问题时,相应的子串有:a[0]->a[n],a[1]->a[n]...a[n-1]->a[n],a[n],共n+1个子串.
这个问题也可以想成:a[0]->a[n-1],a[1]->a[n-1]...a[n-1],0,这n+1个子串加上a[n],哪个最大.
注:关于上述子串的最后一个0子串:如果前面的子串都是负数,那加上a[n]比a[n]小,那就加上0,这个问题答案就是a[n].
这时又要考虑a[0]->a[n-1],a[1]->a[n-1]...a[n-1],共n个子串,
也转化成a[0]->a[n-2],a[1]->a[n-2]...a[n-2],0,这n个子串加上a[n-1]的最大值.
一直往前推,就到了a[0]的最大值.最终这个问题就变成了递归问题...
递归因为要从后往前推,需要记录下所有的输入数据.而动态规划可以不记录,读取一个判断一个.
如:读取a[0],sum=a[0],判断,如果sum<0,加上a[1]一定比a[1]小,令sum=0,以后也不再考虑a[0];否则继续.
接着读取a[1],sum=max(sum+a[1],a[1]),同样判断是否小于0.
再读取a[2],sum=max(sum+a[2],a[2]),判断是否小于0.
简单地说,sum就是目前的最佳决策.(像贪心==...)
所以方程是:sum=max(sum+a[i],a[i])
完了完了,根本写不清楚...orz...
#include <cstdio> #include <iostream> #include <string> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <vector> #define PI acos(-1.0) #define ms(a) memset(a,0,sizeof(a)) #define msp memset(mp,0,sizeof(mp)) #define msv memset(vis,0,sizeof(vis)) #define msd memset(dp,0,sizeof(dp)) using namespace std; //#define LOCAL int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); //freopen("out.txt","w",stdout); #endif // LOCAL //ios::sync_with_stdio(false); int N,kase=0; cin>>N; while(N--) { kase++; int n; cin>>n; int num; int sum=0,maxx=-1001,l=0,r=0,t=1; for(int i=0; i<n; i++) { cin>>num; sum+=num; if(sum>maxx) { maxx=sum; l=t,r=i+1; } if(sum<0) { sum=0; t=i+2; } } printf("Case %d: %d %d %d ",kase,maxx,l,r); if(N!=0)printf(" "); } return 0; }