# 1007. Maximum Subsequence Sum (25)

400 ms

65536 kB

16000 B

Standard

CHEN, Yue

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

### 方法三：分治法求解

//分治算法
int a[999999];

int MAxSubSum(int left,int right)
{
int sum=0;
if(left==right)//基本情况：只有一个元素
sum=a[left]>0?a[left]:0;
else
{
int center=(left+right)/2;
int leftsum=MaxSubSum(left,center);//左半部分
int rightsum=MAxSubSum(center+1,right);//右半部分

//求包含左半部分最右元素的最大和
int s1=0;
int lefts=0;
for(int i=center;i>=left;i--)
{
lefts+=a[i];
if(lefts>s1) s1=lefts;
}

//求包含右半部分最左元素的最大和
int s2=0;
int rights=0;
for(int i=center+;i<=right;i++)
{
rights+=a[i];
if(rights>s2) s2=rights;
}

//取三者最大值
sum=s1+s2;
if(sum<leftsum) sum=leftsum;
if(sum<rightsum) sum=rightsum;
}
return sum;
}

//动态规划算法
int MaxSum(int n)
{
int sum=0,b=0;
for(int i=0;i<n;i++)
{
if(b>0) b+=a[i];
else b=a[i];
if(b>sum) sum=b;
}
return sum;
}

#include <stdlib.h>
#include <stdio.h>
int main()
{
int k,i;
int ThisSum=0,MaxSum;	//当前子列和，最大子列和
int first,tempfirst,last,templast;
scanf("%d",&k);
int a[k];

for(i=0;i<k;i++)
{
scanf("%d",&a[i]);
}
MaxSum=a[0];	//初始化数值
tempfirst=a[0];
templast=a[0];
first=a[0];
last=a[0];
for(i=0;i<k;i++)
{
if(ThisSum>=0)	//当前子列和大于或等于0时，templast移动到当前元素，且当前子列和累加该元素

{
ThisSum+=a[i];
templast=a[i];
}else{	//当前子列和小于0时，当前元素作为新的子列和，templast和tempfirst均为当前元素

ThisSum=a[i];
tempfirst=a[i];
templast=a[i];
}
if(ThisSum>MaxSum)	//当前子列和大于最大子列和时，存储和、起始元素
{
MaxSum=ThisSum;
last=templast;
first=tempfirst;
}
}
if(MaxSum<0)	//当最大子列和小于0，即所有元素都是负数，最大子列和为0，存储起始的元素
{
MaxSum=0;
last=a[k-1];
first=a[0];
}
printf("%d %d %d\n",MaxSum,first,last);
return 0;
} 

• 评论

• 上一篇
• 下一篇