zoukankan      html  css  js  c++  java
  • 最大连续和问题【四种不同的算法】

    给出一个长度n的序列:A1,A2,A3,……,An。求最大连续子段和。
    即:要求找到1<=i<=j<=n,使得A[i]+ A[i+1]+……+A[j]尽量大。

    题目来源:
    洛谷OJ: P1115 最大子段和
    题目描述
    给出一段序列,选出其中连续且非空的一段使得这段和最大。
    输入格式:
    输入文件maxsum1.in的第一行是一个正整数N,表示了序列的长度。
    第2行包含N个绝对值不大于10000的整数A[i],描述了这段序列。
    输出格式:
    输入文件maxsum1.out仅包括1个整数,为最大的子段和是多少。子段的最小长度为1。
    输入样例#1:
    7
    2 -4 3 -1 2 -4 3
    输出样例#1:
    4
    说明
    【样例说明】2 -4 3 -1 2 -4 3
    【数据规模与约定】
    对于40%的数据,有N ≤ 2000。
    对于100%的数据,有N ≤ 200000。

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 long long fun1(int a[],int n)//返回最大连续子段和。O(n^3),可以获取子段位置 
     4 {
     5     int i,j,k;
     6     long long best=a[0],sum;//初始最大值
     7     int bestI=0,bestJ=0;
     8     
     9     for(i=0;i<n;i++)
    10     {
    11         for(j=i;j<n;j++)
    12         {
    13             sum=0;
    14             for(k=i;k<=j;k++) sum=sum+a[k];
    15             if(sum>best) { best=sum; /*bestI=i; bestJ=j;*/ }
    16         }
    17     }
    18     return best;
    19 }
    20 long long fun2(int a[],int n)//返回最大连续子段和。O(n^2),可以求得子段的位置。 
    21 {
    22     int *s=(int *)malloc(sizeof(int)*n);
    23     int i,j,bestI=0,bestJ=0;
    24     long long best,sum;
    25     
    26     s[0]=a[0];
    27     for(i=1;i<n;i++) s[i]=s[i-1]+a[i];
    28     
    29     best=a[0];
    30     for(i=0;i<n;i++)
    31     {
    32         for(j=i;j<n;j++)
    33         {
    34             if(i==0) sum=s[j];
    35             else sum=s[j]-s[i-1];
    36             best=(sum>best?sum:best);
    37             //if(sum>best) { best=sum; bestI=i; bestJ=j; }
    38         }
    39     }
    40     free(s);
    41     return best;
    42 }
    43 long maxSum(int a[],int x,int y)//返回序列a[]在下标[x,y)范围内的最大子段和。O(nlogn),无法求得最大子段位置 
    44 {
    45     long mid,V,L,R;
    46     long max,s1,s2,s3;
    47     int i;
    48     
    49     if(y-x==1)return a[x];//假如只有一个元素,最大子段和就是该元素本身
    50     
    51     mid=x+(y-x)/2;//分治法第一步:划分为[x,m)和[m,y)两个子段
    52     s1=maxSum(a,x,mid);//分治法第二部:递归求解 
    53     s2=maxSum(a,mid,y);
    54     max=(s1>s2?s1:s2);
    55     
    56     V=0;L=a[mid-1];//分治法第三步:合并(1)——从分界点开始往左的最大连续子段和 
    57     for(i=mid-1;i>=x;i--) { V=V+a[i]; L=(V>L?V:L); } 
    58     
    59     V=0;R=a[mid];//分治法第三步:合并(2)——从分界点开始往右的最大连续子段和
    60     for(i=mid;i<y;i++) { V=V+a[i]; R=(V>R?V:R); }
    61     
    62     V=L+R;
    63     return (V>max?V:max);//把子问题的解与L+R比较 
    64 }
    65 long fun4(int a[],int n)//返回a[]的最大子段和
    66 {
    67     long temp,sum;
    68     int i;
    69     temp=a[0];sum=a[0];
    70     for(i=1;i<n;i++)
    71     {
    72         if(temp<0) temp=a[i];
    73         else temp=temp+a[i];
    74         if(temp>sum) sum=temp;
    75     }
    76     return sum;
    77 } 
    78 int main(int argc, char *argv[])
    79 {
    80     int n,i,a[200003];
    81     long long ans;
    82     freopen("testdata.in","r",stdin);
    83     
    84     scanf("%d",&n);
    85     for(i=0;i<n;i++) scanf("%d",&a[i]);
    86     //ans=fun1(a,n);        //超时 
    87     //ans=fun2(a,n);        //得部分分,其余测试点超时 
    88     //ans=maxSum(a,0,n);    //AC
    89     ans=fun4(a,n);            //AC
    90     printf("%lld
    ",ans);
    91     return 0;
    92 }
  • 相关阅读:
    深度分析:SpringBoot异常捕获与封装处理,看完你学会了吗?
    去年去阿里面试,面试官居然问我Java类和对象,我是这样回答的!
    面试官:小伙子,你给我详细说一下线程的状态有哪些吧?
    新鲜出炉!JAVA线程池精华篇深度讲解,看完你还怕面试被问到吗?
    面试官:小伙子,你给我讲一下java类加载机制和内存模型吧
    深度分析:面试90%被问到的多线程、创建线程、线程状态、线程安全,一次性帮你全搞定!
    close与shutdown
    select模型(二 改进服务端)
    select模型(一 改进客户端)
    5种IO模型
  • 原文地址:https://www.cnblogs.com/huashanqingzhu/p/6882678.html
Copyright © 2011-2022 走看看