1. 程式人生 > >DP--HDU 1003求數字串中的最大連續序列(含有DP過程詳細分析)

DP--HDU 1003求數字串中的最大連續序列(含有DP過程詳細分析)

d+ 最大 高亮 esp 序列 cas 最大連續 hdu 1003 for

題意如標題所示。測試數據規模為100000。

首先從DP的角度考慮

狀態:i(數組下標)

狀態轉移方程:

技術分享圖片註:加上“等於零”是為了得到有多解時,的第一個解。(原諒我的字 -_-)

初始邊界狀態極其值:dp[0]。

最大連續序列和:定義一個max_sum=dp[0],從前到後,根據狀態轉移方程不斷更新

最大連續序列的起點與終點(這個我覺的非常容易寫錯):定義begin與end初始為零,當狀態轉移方程滿足上半部分時,end=i;滿足下半部分時,令temp=i,直到後面有dp[i]>max_sum時,begin=i;

下面展示了一種錯誤情況,高亮部分為錯誤部分(好像看不到高亮,我又加了註釋),很容易修改,不再給出ac代碼,一個可以測試出其錯誤的樣例是:

2
9 100 5 -105 -1 -1 10 10 10 1000
7 0 6 -1 1 -6 7 -5

錯誤代碼:

#include <iostream>
using namespace std;

const int maxn=100000+10;  

int dp[maxn];

int main()  
{  
	freopen("in.txt","r",stdin);
	int c,n,begin,end;
	int count=0;
	scanf("%d",&c);
	for(int i=0;i<c;i++){
        scanf("%d",&n);
			for(int l=0;l<n;l++){
				scanf("%d",&dp[l]);
			}
			printf("Case %d:\n",++count);
			begin=end=0;
			int max_sum=dp[0];
			if(n>1)
			for(int l=1;l<n;l++){                //不能改為 l<=n 
				if( dp[l-1]>=0 ){
					dp[l]+=dp[l-1];
				}
				else{
					if(dp[l]>max_sum)   //錯誤部分
					begin=l;            //錯誤部分
} if(max_sum<dp[l]){ max_sum=dp[l]; end=l; } max_sum=max_sum>dp[l]?max_sum:dp[l]; } printf("%d %d %d\n",max_sum,begin+1,end+1); if(i!=(c-1)) cout<<endl; } return 0; }

DP--HDU 1003求數字串中的最大連續序列(含有DP過程詳細分析)