dp經典問題-最大連續子序列和 hdu1003
阿新 • • 發佈:2018-11-25
i++ 最長子序列和 cnblogs ++ n) 代碼 str .com 個數
題目描述:
這道題我先後做過三遍,結果每一遍都沒有做出來。今天再仔仔細細的研究了一下,才發現用動態規劃更好理解。
關於求最大連續子序列和的博文轉載如下:https://www.cnblogs.com/coderJiebao/p/Algorithmofnotes27.html
最大連續子序列和的特點就是這個和一定比它的子序列中任何一個數要大,所以就有了判斷條件。
已知一序列:把數列第一個數存入dp[0],從第一個數開始遍歷,用一個dp數組去存兩數之間的最大子序列和,因此得出動態轉移方程式dp[i]=max(dp[i-1]+a[i],a[i]);
代碼實現:
#include <iostream> #include<cstdio> using namespace std; int a[100001],dp[100001]; int main() { int T,n,i=0; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d",&a[i]); } dp[0] = a[0]; int start = 0,end = 0,max = -1001;int first = 0,last = 0; for(int i=0;i<n;i++) { if(dp[i-1]+a[i]>=a[i]) //判斷條件 { dp[i] = dp[i-1]+a[i]; end = i; } else//如果最長子序列和比a[i]還小,那麽就從當前a[i]開始重新遍歷 { dp[i] = a[i]; start= end = i; } if(max<dp[i]) { max = dp[i]; first = start; last = end; } } printf("Case %d:\n%d %d %d\n",++i,max,first+1,last+1); if(T!=0) { printf("\n"); } } return 0; }
另一個改進的版本:
#include<iostream> #include<cstdio> using namespace std; int main() { int t,n,a[100010],Case=1; int thissum,maxsum,begin,end,postion; cin>>t; while(t--){ cin>>n; for(int i=0; i<n; i++) cin>>a[i]; thissum=maxsum=a[0]; begin=end=postion=0; for(int i=1; i<n; i++){ if(thissum+a[i]<a[i]){//如對於6 -1 0 3 -4 3 2這組數據來說,就會更新postion thissum=a[i]; postion=i; } else thissum+=a[i]; if(thissum>maxsum){ maxsum=thissum; begin=postion; end=i; } } printf("Case %d:\n%d %d %d\n",Case++,maxsum,begin+1,end+1); } return 0; }
dp經典問題-最大連續子序列和 hdu1003