PAT 1007

1007 Maximum Subsequence Sum (25分)


Given a sequence of K integers { N​1​​, N​2​​, ..., N​K​​ }. A continuous subsequence is defined to be { N​i​​, N​i+1​​, ..., N​j​​ } 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

一、试题分析: 

  • 题目要求:求出连续子序列和最大时的总和、首位数、末位数
  • 对于子序列问题首先应该想到动态规划方法:求循环到当前数N[i]时的最大总和(将循环到N[i-1]、循环到N[i]的状态进行比较)
  • 最后题目要求:全为负数则输出0、整个序列的首位、末位

二、解题思路:

  • 列出所需变量:
  1. temp:循环到当前数的最大总和(初始化为0)
  2. maxn:k次最大总和的最大值(初始化为负值:便于和temp比较并更新;若一次都没有更新则表示全为负数)
  3. left、right、p:最大序列的首位、末位、记录多次序列的首位
  • 全为负数:输出0、整个序列的首位、末位
  • 只要有一个正数:最大子序列必定从正数开始
  1. 如果到当前数的最大总和 <0(等到从正数开始 / 记录新的序列)更新动态最大总和及动态首位下标:temp=0、p=i+1
  2. 如果到当前数的最大总和 >0 且序列和更大(加了一个正数)更新最大子序列总和、首位、末位下标:maxn=temp、left=p、right=i
  3. 如果到当前数的最大总和 >0 但序列和没有更大(加了一个负数):只需取前面最大序列和的情况,无需做任何操作
#include<iostream>
using namespace std;

int main()
{
	int k,i;
	cin>>k;
	int a[k];
	for(i=0;i<k;i++)
        cin>>a[i];
	int temp=0; //循环到当前数的总和
	int maxn=-1; //k次最大总和的最大值
	int left=0;
	int right=k-1;
	int p=0;
	for(i=0;i<k;i++)
	{
		temp+=a[i]; 
		if(temp<0) //重新记录新的序列,更新新的最大总和及首位下标
		{
			temp=0;
			p=i+1;
		}
		else if(temp>maxn)
		{
			maxn=temp;
			left=p;
			right=i;
		}
	}
	if(maxn<0) //全为负数
        maxn=0; 
	cout<<maxn<<' '<<a[left]<<' '<<a[right];
	return 0;
}
发布了28 篇原创文章 · 获赞 2 · 访问量 6564

猜你喜欢

转载自blog.csdn.net/Ariel_x/article/details/104025699