HDU 1003 Max Sum(动态规划)

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
 
Sample Output
Case 1: 14 1 4
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:\n%d %d %d\n",kase,maxx,l,r);
        if(N!=0)printf("\n");
    }
    return 0;
}
View Code

 

posted @ 2016-02-24 12:05  ACMSaga  阅读(166)  评论(0编辑  收藏  举报