zoukankan      html  css  js  c++  java
  • 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:
    %d %d %d
    ",kase,maxx,l,r);
            if(N!=0)printf("
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ASP.NET MVC5+ 路由特性
    老李分享:大数据,数据库,数据仓库之间是什么关系
    老李分享:DBA
    老李提问:开源家族你认识几个
    米尔格伦连锁信实验
    老李分享:六度分隔理论
    三者关系
    老李分享:JDK,JRE,JVM区别与联系
    Linux简介与厂商版本下
    Linux简介与厂商版本上
  • 原文地址:https://www.cnblogs.com/gpsx/p/5212488.html
Copyright © 2011-2022 走看看