最大连续和问题【四种不同的算法】

给出一个长度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\n",ans);
91     return 0;
92 }
时间: 2024-10-23 18:39:16

最大连续和问题【四种不同的算法】的相关文章

JVM的判断对象是否已死和四种垃圾回收算法总结

面试题一:判断对象是否已死 判断对象是否已死就是找出哪些对象是已经死掉的,以后不会再用到的,就像地上有废纸.饮料瓶和百元大钞,扫地前要先判断出地上废纸和饮料瓶是垃圾,百元大钞不是垃圾.判断对象是否已死有引用计数算法和可达性分析算法. 1.引用计数算法 给每一个对象添加一个引用计数器,每当有一个地方引用它时,计数器值加 1:每当有一个地方不再引用它时,计数器值减 1,这样只要计数器的值不为 0,就说明还有地方引用它,它就不是无用的对象.如下图,对象 2 有 1 个引用,它的引用计数器值为 1,对象

php四种基础排序算法的运行时间比较!

/** * php四种基础排序算法的运行时间比较 * @authors Jesse (jesse152@163.com) * @date 2016-08-11 07:12:14 */ //冒泡排序法 function bubbleSort($array){ $temp = 0; for($i = 0;$i < count($array) -1;$i++){ for($j = 0;$j < count($array) - 1 -$i;$j++){ if($array[$j] > $arra

php四种基础排序算法的运行时间比较

/** * php四种基础排序算法的运行时间比较 * @authors Jesse (jesse152@163.com) * @date 2016-08-11 07:12:14 */ //冒泡排序法 function bubbleSort($array){ $temp = 0; for($i = 0;$i < count($array) -1;$i++){ for($j = 0;$j < count($array) - 1 -$i;$j++){ if($array[$j] > $arra

PHP四种基本排序算法

PHP的四种基本排序算法为:冒泡排序.插入排序.选择排序和快速排序. 下面是我整理出来的算法代码: 1. 冒泡排序: 思路:对数组进行多轮冒泡,每一轮对数组中的元素两两比较,调整位置,冒出一个最大的数来. //简单版: function bubbleSort($arr) { $n = count($arr); for($i=1;$i<$n;$i++) {   //冒泡的轮数(最多$n-1轮) for($j=0;$j<$n-1;$j++) {   //每一轮冒泡(两两比较,大者后移) if($a

四种迷宫生成算法

简介 所谓迷宫生成算法,就是用以生成随机的迷宫的算法 迷宫生成算法是处于这样一个场景: 一个row行,col列的网格地图,一开始默认所有网格四周的墙是封闭的 要求在网格地图边缘,也就是网格的边上打通2面墙 所有网格都至少保证网格周围至少有一堵墙打通 所有网格都能通过打通的墙能形成一条通路 博主已实现RecursiveBacktracking(递归回溯),RecursiveSegmentation(递归分割),随机Prim算法,Kruskal+并查集四种迷宫生成算法,这篇文章主要对这四种算法进行简

PHP 四种基本排序算法的代码实现

许多人都说算法是程序的核心,算法的好坏决定了程序的质量.作为一个初级phper,虽然很少接触到算法方面的东西.但是对于基本的排序算法还是应该掌握的,它是程序开发的必备工具.这里介绍冒泡排序,插入排序,选择排序,快速排序四种基本算法,分析一下算法的思路. 前提:分别用冒泡排序法,快速排序法,选择排序法,插入排序法将下面数组中的值按照从小到大的顺序进行排序.$arr(1,43,54,62,21,66,32,78,36,76,39); 1. 冒泡排序 思路分析:在要排序的一组数中,对当前还未排好的序列

PHP 四种基本排序算法的代码实现(2)

许多人都说算法是程序的核心,算法的好坏决定了程序的质量.作为一个初级phper,虽然很少接触到算法方面的东西.但是对于基本的排序算法还是应该掌握的,它是程序开发的必备工具.这里介绍冒泡排序,插入排序,选择排序,快速排序四种基本算法,分析一下算法的思路. 前提:分别用冒泡排序法,快速排序法,选择排序法,插入排序法将下面数组中的值按照从小到大的顺序进行排序. $arr(1,43,54,62,21,66,32,78,36,76,39); 1. 冒泡排序 思路分析:在要排序的一组数中,对当前还未排好的序

四种nlogn排序算法代码

1.快速排序:不稳定排序,最好情况O(nlogn),最差情况O(n^2).平均情况在所有nlogn排序中最快的排序 快速排序分两步第一步是将l-r区间进行分块(假设将区间最后一个作为关键字)前面一块的数比小于等于关键字,后面一块大于关键字,并返回第一个大于关键字的位置,即函数partition第二部是对l~pos-1 和pos+1~r分别进行快速排序. 递归式:int partition(int l,int r){    int k=r;    while(l<r)    {        in

PHP实现四种基本排序算法

前提:分别用冒泡排序法,快速排序法,选择排序法,插入排序法将下面数组中的值按照从小到大的顺序进行排序. $arr(1,43,54,62,21,66,32,78,36,76,39); 1. 冒泡排序 思路分析:在要排序的一组数中,对当前还未排好的序列,从前往后对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒.即,每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换. 代码实现:$arr=array(1,43,54,62,21,66,32,78,36,76,39);  f