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

    问题描述:有一串数字,可正可负也可为0,连续两个或多个数字组成了一个子
    序列,每个子序列都有一个和,求出所有子序列中和最大的一个。
    例如输入的数组为3 6 -7 -1 4 3 -2 -5 10 -3,则和最大的子序列为3 6 -7 -1
    4 3 -2 -5 10,最大和为11
     
    分析: 这个问题容易想到的方法是计算出任意两点之间的序列和,取出它们中的最大值,
    时间复杂度为O(n^2)
     
    程序员编程艺术上提到一种二分的方法,将序列分成左右两个部分,分别计算出
    左右两个部分的连续最长子序列,再求出端点分别在左右两边的连续最长子序列,
    它们三个中的最大值就是整个序列上的最长连续子序列,时间复杂度是O(nlogn)
     
    #include <stdio.h>
    #define M 100
     
    int a[M];
     
    int max_sum(int left,int right)
    {
        int leftmax,rightmax;      
        int leftside,rightside;    
        int leftsidemax, rightsidemax;
     
        if(left==right)
     
            return a[left]>0?a[left]:0;
        leftside=leftsidemax=0;
        rightside=rightsidemax=0;
     
        int middle=(left+right)/2;
        leftmax=max_sum(left,middle);
        rightmax=max_sum(middle+1,right);
     
       
        for(int i=middle;i>=left;i--)
        {
            leftside+=a[i];
            if(leftside>leftsidemax)
                leftsidemax=leftside;
        }
       
        for(int i=middle+1;i<=right;i++)
        {
            rightside+=a[i];
            if(rightside>rightsidemax)
                rightsidemax=rightside;
        }
        int maxside=leftmax>rightmax?leftmax:rightmax;
        int middleside=leftsidemax+rightsidemax;
        int max=maxside>middleside?maxside:middleside;
        return max;
    }
     
    int main()
    {
        freopen("in","r",stdin);
        int n;
        scanf("%d", &n);
        for(int i = 0; i < n; i++)
            scanf("%d", &a[i]);
        int max = max_sum(0, n-1);
        printf("%d\n", max);
    }
     
     
    将数字存放在数组中,下标从0到n-1,假如已经求出以i为末尾的最大连续子序
    列之和为sum[i],则如果要求以i+1为结尾的最大连续子序列的和sum[i+1],有
    sum[i+1]=sum[i]>0 ? sum[i]+a[i+1] : a[i+1];找出它们中的最大值
     
    int a[M];
    int sum[M];
     
    int max_sum(int left, int right)
    {
        int max=0;            #考虑全是负数的情况改为max=a[left]
        sum[left]=a[left];
        for(int i=left+1;i<=right;i++)
        {
            sum[i]=sum[i-1]>0?sum[i-1]+a[i]:a[i];
            if(sum[i]>max)
                max=sum[i];
        }
        return max;
    }
  • 相关阅读:
    Oracle->oracle单实例Shell脚本[20180122]
    oracle 11g grid软件安装[20180121]
    MySQL-5.7.20主从复制测试[20180110]
    Sonarqube中文插件-Linux[20180105]
    Sonar安装-Linux[20171227]
    (Linux 日常命令)[20171225]
    ThreadLocal的实现机制
    LruCache源码分析
    命令提示符怎么以管理员方式打开
    Eslint 从入门到放弃 http://blog.csdn.net/fay462298322/article/details/74931092
  • 原文地址:https://www.cnblogs.com/qianye/p/2786366.html
Copyright © 2011-2022 走看看