4.1最大子数组问题
这类问题之前我都是用dp做的,通过刷新下标st与ed,来找到答案。
pst指的是可能的开头(possible start);
我的做法也是练习4.1-5的一个答案
pst=st=ed=1,maxsum=-inf,sum=0;
for(i=1;i<=n;i++)
{
sum+=a[i];
if(sum>=maxsum) st=pst,ed=i,maxsum=sum;
if(sum<=0) pst=i+1,sum=0;
}
printf("%lld\n",maxsum);
下面是分治法解决最大子数组问题的伪代码
长的我都不想啃QAQ



纯翻译代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn=1000000;
ll n,A[maxn],i;
ll findmax(ll A[],ll left,ll right)
{
ll MaxLeftSum,MaxRightSum;
ll MaxLeftBorderSum,MaxRightBorderSum;
ll LeftBorderSum,RightBorderSum;
if(left==right)
return A[left];
ll mid=(left+right)/2;
MaxLeftSum=findmax(A,left,mid);
MaxRightSum=findmax(A,mid+1,right);
MaxLeftBorderSum=LeftBorderSum=0;
for(i=mid;i>=left;i--)
{
LeftBorderSum+=A[i];
MaxLeftBorderSum=max(MaxLeftBorderSum,LeftBorderSum);
}
MaxRightBorderSum=RightBorderSum=0;
for(i=mid+1;i<=right;i++)
{
RightBorderSum+=A[i];
MaxRightBorderSum=max(MaxRightBorderSum,RightBorderSum);
}
return max(max(MaxLeftSum,MaxRightSum),max(MaxRightSum,MaxLeftBorderSum+MaxRightBorderSum));
}
int main()
{
scanf("%lld",&n);
for(i=1;i<=n;i++)
scanf("%lld",&A[i]);
printf("%lld\n",findmax(A,1,n));
return 0;
}
这题用代码实现难度还是挺大的QAQ
那个返回三个数把我卡了好久
算法解析:
mid=(st+ed)/2;
把所有子串分为三种,
case1.头尾都在st到mid
case2.头尾都在mid+1到ed
case3.头在st到mid,尾在mid+1到ed
答案就为max(case1,case2,case3)
case1,2,3继续递归,直到只剩一个元素
本文详细解析了最大子数组问题的两种求解方法:动态规划和分治法。介绍了通过刷新下标找到最大子数组的动态规划算法,并深入探讨了分治法的递归过程,包括如何将问题分解为三种情况并求解最大和。

被折叠的 条评论
为什么被折叠?



