Max Sum 动规小练

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;
}
发布了130 篇原创文章 · 获赞 3 · 访问量 1622

猜你喜欢

转载自blog.csdn.net/yeyuluo/article/details/103911924
今日推荐