Max Sum
原题链接https://vjudge.net/contest/349774#problem/A
两种方法
第一种
前缀和:使用一个数组记录前i项相加的和,用最大的减去最小的即为正确答案。
要每次比较最大值,更新取的集合的位置,当有新的最小值时,要更新起点,
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
long long sum[100005];
int main()
{
long long t,num=1;
scanf("%lld",&t);
while(t--)
{
long long n;
scanf("%lld",&n);
long long i,j,sum1;
sum[0]=0;
long long maxx=-10086,begin=0,start=0,end=0;
for(i=1; i<=n; i++)
{
scanf("%lld",&sum1);
sum[i]=sum[i-1]+sum1;
if(sum[i]-sum[begin]>maxx)
{
maxx=sum[i]-sum[begin];
start=begin+1;//更新起点
end=i;//更新终点
}
if(sum[i]<sum[begin])
{
begin=i;//begin记录最小值所取的位置
}
}
printf("Case %lld:\n",num);
num++;
printf("%lld %lld %lld\n",maxx,start,end);
if(t)
{
printf("\n");
}
}
return 0;
}
第二种
采用的思想是s[i,j]=a[i]+a[i+1]+…+a[j];
如果s[i,j]<0,也就是s[i,j]+a[j+1]<a[j+1]就没有必要继续累加下去了
从a[j+1]开始再次计算
每次比较答案更新最大值,记录位置
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
long long sum[100005];
int main()
{
long long t,k=0;
scanf("%lld",&t);
while(t--)
{
k++;
long long i,n,begin=0,start=0,sum1=0,max=-1008610086;
scanf("%lld",&n);
memset(sum,0,sizeof(sum));
for(i=1; i<=n; i++)
{
scanf("%lld",&sum[i]);
}
begin=1;
start=1;
long long end=1;
for(i=1;i<=n;i++)
{
sum1+=sum[i];
if(sum1>max)
{
start=begin;
end=i;
max=sum1;
}
if(sum1<0)
{
begin=i+1;
sum1=0;
}
}
printf("Case %lld:\n",k);
printf("%lld %lld %lld\n",max,start,end);
if(t>0)
{
printf("\n");
}
}
return 0;
}