最大连续子列和(递归与分治)

本文深入解析分治算法的三步法:划分问题、递归求解与合并问题,通过示例代码详细展示了如何利用分治算法求解最大连续序列和问题,时间复杂度达到O(nlogn)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分治算法一般分为3个步骤:
1.划分问题:把问题的实例划分成若干子问题;
2.递归求解:递归解决子问题;
3.合并问题:合并子问题的解得到原问题的解。

分析此题:此题的答案会在以下三种情况中:
1.所求子列完全包含在左半部分;
2.所求子列完全包含在右半部分;
3.所求子列横跨左右两个部分。
本题中,每个子问题的解都会在以上三种情况中出现,于是,我们可以将原序列划分成左右尽量相等的两半,并对接下来的两半进行不断的划分,分解出多个子问题,再用递归求解出每个子问题的最优解,最终将每个子问题的解合并起来,就得到了原序列的最优解。
对于第三种情况,以分割点为起点的向左的最大连续序列和,以分割点为起点的向右的最大连续序列和,两者相加即为第三种情况的答案。

代码如下:(时间复杂度O(nlogn))

#include<cstdio>
#include<algorithm>
using namespace std;
int a[100005];
int maxs(int x,int y)  //求出数组在[x,y)中的最大连续和
{
int v,L,R,maxsum;  //v用于数据处理,L求出从分界点开始往左的最大连续和,R求出向右的最大连续和,maxsum求出完全位于左半部分或者右半部分的最大和
if(y-x==1) return a[x];  //***只有一个元素时直接返回***(重要,否则会死循环)
int m=x+(y-x)/2;  //***建议写成这种形式***
maxsum=max(maxs(x,m),maxs(m,y));   //递归求解
v=0;L=a[m-1];
for(int i=m-1;i>=x;i--)  //开始计算L
   L=max(L,v+=a[i]); 
v=0;R=a[m];
for(int i=m;i<=y-1;i++)  //开始计算R
   R=max(R,v+=a[i]);
return max(maxsum,L+R);  //最终返回值为,三种答案中 的最大者
}
int main()
{
int T,n;
int i,j;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=0;i<=n-1;i++)
   scanf("%d",&a[i]);
printf("%d\n",maxs(0,n));
}
return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值