您的位置:首页 > 其它

最大子段和

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

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: