一个整数序列,选出其中连续且非空的一段使得这段和最大。
注意当题目要求输入输出的数据量很大时,尽量使用scanf和printf。 c++提供的cin和cout速度比较慢,有可能在读取数据和输出数据时导致超时。输入格式
第一行是一个正整数N,表示了序列的长度(0=<N<=200000)。
第二行包含N个绝对值不大于10000的整数ai。
输出格式
一个整数,为最大的子段和。子段的最小长度为1。数据确保结果在类型int范围内。
输入样例
7
2 -4 3 -1 2 -4 3
输出样例
4

知识点:最大子段和是一个经典的题目。有三大类作法,暴力枚举、前缀和+递推、动态规划。

(一)暴力枚举

既然是子段和,那么可以枚举子段的左右两个端点确定字段范围,计算子段和。复杂度O(n^3)

int main()
{int i,j,k,n,a[200005],maxs;cin>>n;for(i=1; i<=n; i++)cin>>a[i];maxs=a[1];for(i=1; i<=n; i++)/**< i和j为左右端点 */for(j=i; j<=n; j++){int sum=0;for(k=i; k<=j; k++)/**< 求子段[i,j]的和 */sum+=a[k];maxs=max(maxs,sum);}cout<<maxs;return 0;
}

(二)前缀和数组

前缀和数组是一种能快速求区间和(子段和)的数据结构,递归公式s[i]=s[i-1]+a[i],它要求原始数据序列不能有任何改动。

用前缀和数组可以优化上面暴力枚举中求子段和的代码,此时复杂度O(n^2)。进一步可以想到,以X为右端点的最大子段和一定是s[X]- min(0,s[1],s[2]......s[X-1]),而min(0,s[1],s[2]......s[X-1])在处理时可以递推得到,无需再写循环语句。此时整个算法复杂度O(n)。

前缀和数组同样可以应用到更高维度,例如二维数组的前缀和递推公式s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1];同样的思想也能用于求二维的“最大子矩阵”。

int main()
{int i,j,k,n,a[200005],s[200005]= {0},maxs=0;cin>>n;for(i=1; i<=n; i++)cin>>a[i];for(i=1; i<=n; i++)/**< 构造前缀和数组,区间[L,R]的值可以用s[R]-S[L-1]快速得到 */s[i]=s[i-1]+a[i];maxs=a[1];int minv=0;/**< minv用于存储s[1...i-1]的最小值 */for(i=1; i<=n; i++){maxs=max(maxs,s[i]-minv);/**< 以i为右端点的最大字段和一定是s[i]-minv */minv=min(minv,s[i]);/**< 递推minv,为下一次i+1作准备 */}cout<<maxs;return 0;
}

(三)动态规划法

动态规划的思想是假定前 i-1 个数据答案已知时,第i个的答案 一定可以通过前i-1个答案推导出来。在最大字段和问题上,以i为右端点的最大子段和只有两种可能:(1)只有a[i];(2)以[i-1]为右端点的最大子段和+a[i]。可以思考下,不会有其他的可能性。

因为一次递推就可以解决问题(简言之每个数据只被使用一次),下述代码并没有构建数组来存储动态规划的中间结果。

int main()
{int i,j,k,n,a;int maxs,sum;cin>>n;cin>>maxs;/**< 先读一个数据,题目要求字段长度至少为1 */sum=maxs;for(i=2;i<=n;i++){scanf("%d",&a);/**< 对于第i个数字来说,或者和前面的数据一起求和,或者自立门户 */sum=sum<0?a:sum+a;/**< 前面的和大于等于0,连接效果好,不然还不如自立门户 */maxs=max(maxs,sum);}cout<<maxs;return 0;
}

18708 最大子段和相关推荐

  1. scau数据结构习题

    18708 最大子段和 时间限制:1000MS 代码长度限制:10KB 提交次数:0 通过次数:0 题型: 编程题 语言: 不限定 Description 一个整数序列,选出其中连续且非空的一段使得这 ...

  2. 关于最大子段和线性算法的证明

    重复题目: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值.要求时间复杂度为O(n). 此题最初载于 http:/ ...

  3. 洛谷——1115 最大子段和(区间DP)

    题目描述 给出一段序列,选出其中连续且非空的一段使得这段和最大. 输入输出格式 输入格式: 输入文件maxsum1.in的第一行是一个正整数N,表示了序列的长度. 第2行包含N个绝对值不大于10000 ...

  4. [SDOI2011]染色 (线段树维护子段问题+树剖)

    题意: 给定一棵 n 个节点的无根树,共有 m 个操作,操作分为两种: 1.将节点 a 到节点 b 的路径上的所有点(包括 a 和 b)都染成颜色 c. 2.询问节点 a 到节点 b 的路径上的颜色段 ...

  5. 贪心 ---- Educational Codeforces Round 90 (Rated for Div. 2)D Maximum Sum on Even Positions[偶数子段最大和]

    题目链接 题目大意:给你一个序列你可以选择一个连续的子段将其反转,反转后使得偶数位置上的数字和最大 1.很明显我们可以看出反转的字符串的长度一定是偶数的,因为是奇数的话偶数位还是在偶数位不变所以没有用 ...

  6. 解题报告:SP1043 GSS4 - Can you answer these queries III(GSS线段树八部曲之三)(区间最大连续子段和)

    要注意输入的数据有坑,x可能大于y- 我们可以模块化编程,使得整个代码井井有条 函数可以重名,只要参数不一样就行. 来源 yxc老师的上课板书 然后就是简单的代码了 #include<iostr ...

  7. 51nod 最大M子段和系列

    1052 最大M子段和 N个整数组成的序列a[1],a[2],a[3],-,a[n],将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的.如果M >= N个数中正数的个数,那么输出所 ...

  8. pku1050----To the Max(求矩阵的最大子段和)

    336K 16MS GCC 627B 2009-01-12 20:44:31 一维的很简单, 就判断一个大于小于0的情况.(两个分支).(求解过程中可不用建立数组c) 对于二维的 通过一个循环 for ...

  9. 最大子段和问题分析和总结

    最大子段和问题(Maximum Interval Sum) 经典的动态规划问题,几乎所有的算法教材都会提到.本文将分析最大子段和问题的几种不同效率的解法,以及最大子段和问题的扩展和运用. 一.问题描述 ...

最新文章

  1. python3 url编码 空格 + 简介
  2. PHP消息队列用法实例分析
  3. 【JavaSE_08】Java中static、继承、重写-思维导图
  4. 设置最小值与最大值 css,一文学会使用 CSS 中的 min(), max(), clamp() 以及它们的使用场景...
  5. Swift与C++混编 OpenCV初体验 图片打码~
  6. KMP算法详解及各种应用
  7. 《剑指offer》删除链表中重复的节点
  8. 简化得最没道理的6个汉字,让人大跌眼镜
  9. 2019年7月9日星期二(C语言)
  10. 微信付费阅读支付宝可用,iOS抽成30%;苹果安卓充电器或统一;UOS 20发布 | 极客头条...
  11. 苹果mac屏幕录像软件:ScreenFlow
  12. 基于JavaSwing+MySql的学生信息管理系统
  13. JAVA实现从Linux服务器上下载文件
  14. 现代电力系统分析王锡凡pdf_一对一论文定制 | 电子工程:电力系统潮流及最优潮流算法研究...
  15. arcgis测量工具测量类型无法选择平面
  16. 视觉SLAM和激光SLAM的实现
  17. html中竖线怎么写,网页中竖线的几种做法
  18. 几种国内芯片测序格式和 Illumina Omni 位点集格式的对比
  19. 美国程序员把工作外包给中国程序员,啥也不干年入 20 万美元,这操作也是骚...
  20. android去掉开机锁屏,android 去掉锁屏

热门文章

  1. 微信开发学习:输入城市+天气接收天气预报,非非非非常好玩
  2. html移除单个css样式,jq如何移除css样式?
  3. 【macOS游戏】殖民者
  4. java中的编译器是什么,java – JVM中的JIT编译器究竟是什么?
  5. opencv 智能答卷识别系统(二) 自动阅卷
  6. Java(5)数组、二维数组
  7. 用友后台数据库如何彻底删除
  8. python中for循环流程图_Python循环语句
  9. Cannot resolve com.xxx.xxx:xxx:x.x.x
  10. C++11 左值、右值、右值引用详解