导航

NYOJ 44-字串和

Posted on 2013-07-31 09:33  勇敢的炮灰  阅读(304)  评论(0)    收藏  举报

点击打开链接

子串和

时间限制:5000 ms  |  内存限制:65535 KB
难度:3
描述
给定一整型数列{a1,a2...,an},找出连续非空子串{ax,ax+1,...,ay},使得该子序列的和最大,其中,1<=x<=y<=n。
输入
第一行是一个整数N(N<=10)表示测试数据的组数)
每组测试数据的第一行是一个整数n表示序列中共有n个整数,随后的一行里有n个整数I(-100=<I<=100),表示数列中的所有元素。(0<n<=1000000)
输出
对于每组测试数据输出和最大的连续子串的和。
样例输入
1
5
1 2 -1 3 -2
样例输出
5

这个题解法有很多,最快的一种就是把数列分成若干个小段,每个小段有一个起始点,设置一个变量sum记录从起始点到当前的总和,一个max记录整个过程所有小段的最大sum值,从数列第一个位置开始循环,sum累加数列的和,如果sum小于等于0,那么说明从前一个起始点到当前位置已经独立为一小段,不会对其他段的sum增加不会起任何正面作用,那么从当前位置sum清零,把当前位置变为一个新的起始点重新开始计数;如果当前sum > max,说明出现了从起始点到当前位置总和出现了新的最大值,那么max = sum;当循环完所有的数,max里面存的就是我们想要的答案,这里有一个陷阱就是如果所有数都小于0,那么上面的办法就会得出一个结果0,这肯定是错误的,整个过程中还要加一段判断如果输入的数是负数,那么就要拿来和max比较一下,如果比max大,那么就max = 这个负数,这样下来如果全是负数,那么就会留下一个最大的负数,而不是0

 
#include<stdio.h>
int main()
{
	int sum , max , num , i , j , k;

	scanf("%d" , &i);
	while(i--)
	{
		scanf("%d" , &j);
		for(k = 0 , sum = 0 , max = -400000000 ; k < j ; k++)
		{
			scanf("%d" , &num);
			if(num > 0)
			{
				sum += num;
				if(sum > max)
					max = sum;
			}
			else 
			{
				if(num > max)
				{
					max = num;
					continue;
				}
				else
					sum+= num;
				if(sum < 0)
					sum = 0;
			}
		}
		printf("%d\n" , max);
	}

	return 0;
}