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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章