看题目第一反应是队列:
但因为不知道子段的长度,所以很难判断何时出队列;
思路1:贪心
思路2:线段树式的递归
比较短,理解是关键
//luogu1115:最大子段和
//贪心
#include
using namespace std;
int n,x,s=0,ans;
int main()
{
scanf("%d",&n);
scanf("%d",&x);//第一个数字单独存储
s=x;
ans=x;
if(s<0) s=0;
for(int i=2;i<=n;i++)
{
scanf("%d",&x);
s+=x;//前缀和
if(ans
//luogu1115:最大子段和
//利用类似线段树的思想
//用递归的来做
#include
using namespace std;
const int mx=2e5+5,mi=-2e5+5;
int a[mx],n;
int dfs(int l,int r)
{
if(l==r) return a[l]; //最下层的位置
int mid=(l+r)/2,s1=mi,s2=mi;
int s=0;
for(int i=mid;i>=l;i--)//从中间向左:求出左边的最大连续和
{
s+=a[i];
s1=max(s1,s);
}
s=0;
for(int i=mid+1;i<=r;i++)//从中间向右:求出右边的最大连续和
{
s+=a[i];
s2=max(s2,s);
}
return max(max(dfs(l,mid),dfs(mid+1,r)),s1+s2);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
int ans=dfs(1,n);
printf("%d",ans);
return 0;
}