zoukankan      html  css  js  c++  java
  • 最大连续区间和

    问题概述

    这是一个经典的问题。

    给定一个长度为n的序列a[1],a[2]...a[n-1],a[n]

    求一个连续的子序列 a[i],a[i+1]...a[j-1],a[j],使得a[i]+a[i+1]...a[j-1]+a[j]最大。

    暴力的方法就是双重循环枚举左右端点,然后直接找最大的就好了。 但是算法的复杂度是 O(N^2) 不够优秀

     

    动态规划解法  复杂度O(n) 

    我们让 dp[ i ] 代表以 a[ i ] 为结束的最大连续子段和

    因为是以a[ i ]为结束且是连续子段  那么

    dp[ i ] 要么就是  a[ i ]本身

              要么 就是a[ i ] + 以a[ i-1 ]为结束的最大连续字段和  也就是 a[ i ] + dp[ i - 1 ]

    所以 状态转移方程出来了      dp[i] = max( A[i], dp[i-1]+A[i] )

    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%lld",&a[i]);//输入
        dp[0]=0;
        for(int i=1;i<=n;i++){//状态转移方程
            dp[i]=max(a[i],dp[i-1]+a[i]);
        }
        ll maxn=0;
        for(int i=1;i<=n;i++){//遍历找最大值
            maxn=max(dp[i],maxn);
        }
        printf("%lld
    ",maxn);
    }

    这个算法的常数还是比较大的,我们可以优化下常数

    ll a[maxn];
    ll n,ans,dp;
    int main(){
        scanf("%lld",&n);
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            dp=max(a[i],dp+a[i]);
            ans=max(dp,ans);
        }
        printf("%lld
    ",ans);
    }

    如果我们还想知道这个具体的最大连续区间的左右端点是什么

     1 int a[maxn];
     2 int main() {
     3     //freopen("../in.txt","r",stdin);
     4     int t;
     5     scanf("%d",&t);
     6     int num = 1;
     7     while (t--) {
     8         int n;
     9         scanf("%d",&n);
    10         int ans = -INF,dp = 0,l = 1,r = 1,k = 1;
    11         for (int i = 1;i <= n;i++) {
    12             scanf("%d",&a[i]);
    13             if (dp >= 0) {
    14                 dp += a[i];
    15             }
    16             else {
    17                 dp = a[i];
    18                 k = i;
    19             }
    20             if (dp > ans) {
    21                 ans =  dp;
    22                 l = k;
    23                 r = i;
    24             }
    25         }
    26         printf("Case %d:
    ",num++);
    27         printf("%d %d %d
    ",ans,l,r);
    28         if (t != 0)
    29             printf("
    ");
    30     }
    31     return 0;
    32 }
  • 相关阅读:
    [模板] 循环数组的最大子段和
    [最短路][几何][牛客] [国庆集训派对1]-L-New Game
    [洛谷] P1866 编号
    1115 Counting Nodes in a BST (30 分)
    1106 Lowest Price in Supply Chain (25 分)
    1094 The Largest Generation (25 分)
    1090 Highest Price in Supply Chain (25 分)
    树的遍历
    1086 Tree Traversals Again (25 分)
    1079 Total Sales of Supply Chain (25 分 树
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/12180830.html
Copyright © 2011-2022 走看看