P1115 最大子段和

简介: 最大连续和问题给出一个长度n的序列:A1,A2,A3,……,An。求最大连续子段和。即:要求找到1

最大连续和问题
给出一个长度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
【数据规模与约定】
  对于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 }

动规算法经过修改也可以得到最大连续子段和的位置。参考51Nod动态规划基础篇的内容 

 

 1 long long fun5(int a[],int n)//返回a[]的最大子段和,子函数内部输出该子段起点和终点
 2 {
 3     int start,end,answerStart,answerEnd;
 4     long long endMax,answer;
 5     
 6     answer=a[0];
 7     answerStart=answerEnd=0;
 8     endMax=a[0];start=0;
 9     for(end=1;end<n;end++)
10     {
11         if(endMax<0)
12         {
13             endMax=a[end];
14             start=end;
15         }
16         else endMax=endMax+a[end];
17 
18         if(endMax>answer)
19         {
20             answer=endMax;
21             answerStart=start;
22             answerEnd=end;
23         }
24     }
25     printf("%d %d\n",answerStart+1,answerEnd+1);
26     return answer;
27 } 

 

相关文章
|
存储 缓存 JSON
详解HTTP四种请求:POST、GET、DELETE、PUT
【4月更文挑战第3天】
66845 5
详解HTTP四种请求:POST、GET、DELETE、PUT
|
运维 Linux Shell
linux运维常用系统工作命令
linux常用系统工作命令,vim编辑器知识介绍
240 1
|
算法
7-2 找第k小的数 (20分) —— 分治算法
7-2 找第k小的数 (20分) —— 分治算法
593 0
|
10天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
9天前
|
存储 人工智能 Java
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
本文讲解 Prompt 基本概念与 10 个优化技巧,结合学术分析 AI 应用的需求分析、设计方案,介绍 Spring AI 中 ChatClient 及 Advisors 的使用。
411 130
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
|
3天前
|
存储 安全 前端开发
如何将加密和解密函数应用到实际项目中?
如何将加密和解密函数应用到实际项目中?
199 138
|
9天前
|
人工智能 Java API
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
本文介绍AI大模型的核心概念、分类及开发者学习路径,重点讲解如何选择与接入大模型。项目基于Spring Boot,使用阿里云灵积模型(Qwen-Plus),对比SDK、HTTP、Spring AI和LangChain4j四种接入方式,助力开发者高效构建AI应用。
380 122
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)