zoukankan      html  css  js  c++  java
  • HDU 1231 最大连续子序列 (DP)

    最大连续子序列

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 20439    Accepted Submission(s): 9038


    Problem Description
    给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., 
    Nj },其中 1 <= i <= j <= K。最大连续子序列是所有连续子序列中元素和最大的一个, 
    例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{ 11, -4, 13 },最大和 
    为20。 
    在今年的数据结构考卷中,要求编写程序得到最大和,现在增加一个要求,即还需要输出该 
    子序列的第一个和最后一个元素。
     
    Input
    测试输入包含若干测试用例,每个测试用例占2行,第1行给出正整数K( < 10000 ),第2行给出K个整数,中间用空格分隔。当K为0时,输入结束,该用例不被处理。
     
    Output
    对每个测试用例,在1行里输出最大和、最大连续子序列的第一个和最后一个元 
    素,中间用空格分隔。如果最大连续子序列不唯一,则输出序号i和j最小的那个(如输入样例的第2、3组)。若所有K个元素都是负数,则定义其最大和为0,输出整个序列的首尾元素。 
     
    Sample Input
    6
    -2 11 -4 13 -5 -2
    10
    -10 1 2 3 4 -5 -23 3 7 -21
    6
    5 -8 3 2 5 0
    1
    10
    3
    -1 -5 -2
    3
    -1 0 -2
    0
     
    Sample Output
    20 11 13
    10 1 4
    10 3 5
    10 10 10
    0 -1 -2
    0 0 0
    Hint
    Hint
    Huge input, scanf is recommended.
     
    Source

    这道题要除了要求出最大连续子序列的值之外还要求出连续区间的左边界和右边界

    状态转移方程为dp[i]=max(dp[i-1]+a[i],a[i])

    当dp[i]=a[i]时更新左边界,每次更新最大值的时候再去保存当前的左右边界

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<stdlib.h>
    #include<queue>
    #include<stack>
    #include<algorithm>
    #define LL __int64
    using namespace std;
    const int MAXN=10000+50;
    const int INF=0x3f3f3f3f;
    const double EPS=1e-9;
    int dir4[][2]={{0,1},{1,0},{0,-1},{-1,0}};
    int dir8[][2]={{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};
    int dir_8[][2]={{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1}};
    int n,L,R,a[MAXN],dp[MAXN],maxn,star,en;
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(scanf("%d",&n) && n)
        {
            memset(a,0,sizeof(a));
            memset(dp,0,sizeof(dp));
            maxn=-INF;
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
    
            for(int i=1;i<=n;i++)
            {
                if(i==1) star=a[i],dp[i]=a[i];
                if(dp[i-1]+a[i]<a[i]) dp[i]=a[i],star=a[i];//更新记录的左边界
                else dp[i]=a[i]+dp[i-1];
                if(dp[i]>maxn) maxn=dp[i],L=star,R=a[i];//更新最大值的时候同时也更新下记录的边界,右边界没有必要单独更新
            }
    
            if(maxn>=0)
                printf("%d %d %d
    ",maxn,L,R);
            else
                printf("0 %d %d
    ",a[1],a[n]);
        }
    }
    View Code
  • 相关阅读:
    606. Construct String from Binary Tree
    696. Count Binary Substrings
    POJ 3255 Roadblocks (次短路)
    POJ 2823 Sliding Window (单调队列)
    POJ 1704 Georgia and Bob (博弈)
    UVa 1663 Purifying Machine (二分匹配)
    UVa 10801 Lift Hopping (Dijkstra)
    POJ 3281 Dining (网络流之最大流)
    UVa 11100 The Trip, 2007 (题意+贪心)
    UVaLive 4254 Processor (二分+优先队列)
  • 原文地址:https://www.cnblogs.com/clliff/p/4245846.html
Copyright © 2011-2022 走看看