【PTA】01-复杂度2 Maximum Subsequence Sum

题目:

Given a sequence of K integers { N1​, N2​, ..., NK​ }. A continuous subsequence is defined to be { Ni​, Ni+1​, ..., Nj​ } where 1≤i≤j≤K. The Maximum Subsequence is the continuous subsequence which has the largest sum of its elements. For example, given sequence { -2, 11, -4, 13, -5, -2 }, its maximum subsequence is { 11, -4, 13 } with the largest sum being 20.

Now you are supposed to find the largest sum, together with the first and the last numbers of the maximum subsequence.

Input Specification:

Each input file contains one test case. Each case occupies two lines. The first line contains a positive integer K (≤10000). The second line contains K numbers, separated by a space.

Output Specification:

For each test case, output in one line the largest sum, together with the first and the last numbers of the maximum subsequence. The numbers must be separated by one space, but there must be no extra space at the end of a line. In case that the maximum subsequence is not unique, output the one with the smallest indices i and j (as shown by the sample case). If all the K numbers are negative, then its maximum sum is defined to be 0, and you are supposed to output the first and the last numbers of the whole sequence.

Sample Input:

10
-10 1 2 3 4 -5 -23 3 7 -21

Sample Output:

10 1 4

 解答:

#include<iostream>
using namespace std;
int main()
{
	int k;
	cin>>k;
	int a[k];
	int i,thisSum=0,nowSum=0;
	for(i=0;i<k;i++)
	{
		cin>>a[i];
	}
	int first=a[0],last=a[k-1],now,j=0,time=0;
	for(i=0;i<k;i++)
	{
		if(a[i]<0)
		{
			time++;
		}
	}
	if(time==k)
	{
		nowSum=0;
		first=a[0];
		last=a[k-1];
	}
	else{
		for(i=0;i<k;i++)
		{
			thisSum+=a[i];
			if(thisSum>nowSum)
			{
				nowSum=thisSum;
				last=a[i];
				j=i;	
			}
			else if(thisSum<0)
			{
				thisSum=0;
			}
		}
		now=nowSum;
		for(i=j;i>-1;i--)
		{
			now-=a[i];
			if(now==0)
			{
				first=a[i];
			}
		}
		if(nowSum==0)
		{
			first=0;
			last=0;
		}
	}
	cout<<nowSum<<" "<<first<<" "<<last<<endl;
	return 0;
}

总结:

难点:

①如何得到first和last的值(first为最大和所在数列的第一个数,last为最后一个数)

②测评点4 5 6

解决方法:

①last的值比较容易得到,只需要根据nowSum的更新实时更新last,并记录此时的last对应的数列的位置j,然后把nowSum的值赋给now,从a[j]开始向前,让now一个数字一个数字减去前边的数字,寻找让now=0的最靠前的数,即为所需要的first。

 在这些测评点中,我一开始没有通过的有4,5,6.

4:一开始我没有认真读题,题目明确说明,如果数列全是负数,则和的最大值输出为0,并输出数列的第一个数和最后一个数,所以后来我把它单列了出来,if数列中全为负数,则nowSum=0,first=a[0],last=a[k-1],其余的归到else里。

5:一开始我没有意识到这个问题,如果数列中全为负数和0,则最大值肯定为0,即nowSum=first=last=0,所以我在代码的最后阶段添加了nowSum为0的情况。

6:最大和前面有一段是0,因为题目要求输出最小的i和j对应的数字,最初我只是想,既然最大和前面有一段是0,那么只需要判断如果得出的a[i]的前一项为0的话,就令first=0,然后break跳出循环,结果没有通过测评。后来我意识到最大和前面有一段是0不一定单纯的指数字0,也有可能是5  -5  0  2  -2  0  0  0 1  2  3这种情况,即两个或者多个数字的和为0,所以我修改了代码,删除了break,即只要当now=0,就修改一次first的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值