最大子段和
2017-04-29 20:56
141 查看
最大子段和问题
• 给定长度为 n 的整数序列列 a[ ],求一个区间 [l, r]
• 最大化Σ a[l…r]
直接观察
暴力循环一个l的位置
循环一个r的位置
一个循环求和
复杂度O(n^3)
第一 优化求和
用sum【i】来存前缀和(前i个数的和)
【l,r】的和就是sum【r】-sum【l-1】
在求sum时采用递推的方法
sum【i】=sum【i-1】+a【i】(第i个数)
复杂度O(n)
第二步问题转变为 寻找max[l,r]
[l,r]=sum【r】-sum【l-1】
所以问题转变为求sum【r】-sum【l-1】的最大值
一般做法 直接循环 复杂度n^2
优化做法
维护一个最小值维护 一个最大差值(答案)
正确性:当sum【l-1】减小和sum【r】增大时差值会变大,当我们循环时直接可以直接遍历到r可以知道sum【r】所以我们只要将r前面
最小的sum【l-1】记下可以节约时间而且l-1必定小于r
推论
给定一个 n * n 的矩形,找一个和最大的子矩形?
循环一个上边界,一个下边界,将一列的数的和作为一个数进行一维的最大子段和
显然复杂度n^3
• 给定长度为 n 的整数序列列 a[ ],求一个区间 [l, r]
• 最大化Σ a[l…r]
直接观察
暴力循环一个l的位置
循环一个r的位置
一个循环求和
复杂度O(n^3)
第一 优化求和
用sum【i】来存前缀和(前i个数的和)
【l,r】的和就是sum【r】-sum【l-1】
在求sum时采用递推的方法
sum【i】=sum【i-1】+a【i】(第i个数)
复杂度O(n)
第二步问题转变为 寻找max[l,r]
[l,r]=sum【r】-sum【l-1】
所以问题转变为求sum【r】-sum【l-1】的最大值
一般做法 直接循环 复杂度n^2
优化做法
维护一个最小值维护 一个最大差值(答案)
正确性:当sum【l-1】减小和sum【r】增大时差值会变大,当我们循环时直接可以直接遍历到r可以知道sum【r】所以我们只要将r前面
最小的sum【l-1】记下可以节约时间而且l-1必定小于r
cin>>n; for(int i=1;i,=n;i++) { scanf("%d",&a[i]; a[i]+=a[i-1];//这里直接求前缀和 } int maxn = 0, minn = 999999; for (int i = 1; i <= n; ++i) { minn = min(a[i], minn); maxn = max(maxn, a[i]-minn); } cout<< maxn;
推论
给定一个 n * n 的矩形,找一个和最大的子矩形?
循环一个上边界,一个下边界,将一列的数的和作为一个数进行一维的最大子段和
显然复杂度n^3
相关文章推荐
- 最大子段和(c++)
- 最大子段和
- 51Nod-1254-最大子段和 V2
- 最大子段和的动态规法
- 最大子段和
- hdu 6205 card card card(最大子段和)
- HDU 1024 Max Sum Plus Plus最大m子段和
- 最大子段和
- 动态规划算法--蛮力算法求最大子段和
- 最大子段和
- poj 1050 To the Max(动态规划处理二维最大子段和)
- hdu 1003 最大子段和
- 最大子段和||最大子矩阵和||最大全1子矩阵||最大全1子正方形||
- 最大子段和问题
- hdu 1024 最大M子段和
- 动态规划2:最大子段和问题到最大子矩阵问题(二):最大n子段和问题详谈
- 最大子段和问题(Maximum Interval Sum)
- 51Nod 1049 最大子段和 (DP
- 51 nod 1254 最大子段和 V2(思维)
- 算法笔记——【动态规划】最大子段和