hdu1003 最大子序列的和

题目大意:给出一串数字,求出子序列中的最大和。

思路:典型的dp问题,状态转移方程为:dp[i]=max{dp[i-1],dp[i-1]+a[i]}.设置start和end两个指标,用来记录结果子序列中的开始和结束的位置。

值得注意的是这道题目中的格式要求很多,一开始没太在意所以wrong answer 了好几次。

如下是第一次AC的代码:

# include <iostream>
# include <algorithm>
using namespace std;

int a[100005],dp[100005];

int main ()
{
	int total,t;
	int n,i,k,maxs,start,end;
	scanf("%d",&total);
	t=total;
	while(t--)
	{
		memset(a,0,sizeof(a));
		memset(dp,0,sizeof(dp));
		scanf("%d",&n);
		for(i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
		}
		dp[1]=a[1];
		maxs=dp[1];
		k=start=end=1;
		for(i=2;i<=n;i++)
		{
			if((dp[i-1]+a[i])<a[i])
			{
				dp[i]=a[i];
				k=i;
			}
			else
				dp[i]=dp[i-1]+a[i];
			if(dp[i]>maxs)
			{
				maxs=dp[i];
				start=k;
				end=i;
			}
		}
		printf("%s%d:\n%d %d %d\n","Case ",total-t,maxs,start,end);
		if(t)
		printf("\n");
	}
	//system("pause");
	return 0;
}

之后尝试了下改进,代码如下。因为从上面的循环中可以看出,其实两个数组并没有什么用,完全可以用一个变量来替代,这样就需要在读入数据的同时做处理,边度数据,边累加处理。

# include <iostream>
# include <algorithm>
using namespace std;


int main ()
{
	int total,t;
	int n,i,k,maxs,start,end,sum,a;
	scanf("%d",&total);
	t=total;
	while(t--)
	{
		scanf("%d",&n);
		scanf("%d",&a);
		start=end=k=1;
		maxs=sum=a;
		for(i=2;i<=n;i++)
		{
			scanf("%d",&a);
			sum=sum+a;
			if(sum<a)
			{
			    sum=a;
				k=i;
			}
			if(maxs<sum)
			{
				maxs=sum;
				start=k;
				end=i;
			}
		}
		printf("%s%d:\n%d %d %d\n","Case ",total-t,maxs,start,end);
		if(t)
		printf("\n");
	}
	system("pause");
	return 0;
}


发布了41 篇原创文章 · 获赞 1 · 访问量 1万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章