杭电OJ(HDOJ)1231题:最大连续子序列(动态规划)

题意:

给出一个长度为K的整数序列(有正有负),求出序列的最大连续子序列。并输入最大的和以及最大连续子序列开始的数字和结束的数字。有多个相同的最大连续子序列输出起始和结束位置最小的(即最靠前的最大连续子序列)。测试输入包含若干测试用例,每个测试用例占2行,第1行给出正整数K( < 10000 ),第2行给出K个整数,中间用空格分隔。当K为0时,输入结束,该用例不被处理。若所有K个元素都是负数,则定义其最大和为0,输出整个序列的首尾元素。 

示例输入:

6
-2 11 -4 13 -5 -2
10
-10 1 2 3 4 -5 -23 3 7 -21
6
5 -8 3 2 5 0
1
10
3
-1 -5 -2
3
-1 0 -2
0

示例输出:

20 11 13
10 1 4
10 3 5
10 10 10
0 -1 -2
0 0 0

解决方案:

一个经典的DP问题。注意{-1 0 -2}输出为0 0 0。即最大值可以是0。

#include<stdio.h>
int main()
{
	int arr[10000],i,n;
	int end,start,max;//分别纪录起始下标,结束下标,最大和
	int sum,temp,cnt;//sum,temp用于临时存放子段和与开始下标,cnt存放负数个数
	while(scanf("%d",&n)&&n)
	{
		for(i=0;i<n;i++)
			scanf("%d",arr+i);
		cnt=sum=end=start=temp=0;
		max=arr[0];//max=-1;
		for(i=0;i<n;i++)
		{
			sum+=arr[i];
			if(sum>max)
			{
				end=i;
				start=temp;
				max=sum;
			}
			if(sum<0)
			{
				temp=i+1;//起始位置应为下一个数的下标
				sum=0;
				cnt++;
			}

		}
		if(cnt==n)//负数个数等于n,说明输入的数都是负数
			printf("0 %d %d\n",arr[0],arr[n-1]);
		else
			printf("%d %d %d\n",max,arr[start],arr[end]);
	}
}


你可能感兴趣的:(算法,dp,动态规划,ACM,OJ)