【程式設計網格無水題】【動態規劃篇】之【最大字串和】
阿新 • • 發佈:2018-11-25
Written By MorrowWind,csdnicewing
可以到洛谷的P115上去練習 https://www.luogu.org/problemnew/show/P1115
題目描述
給出資料個數n和一段序列,選出其中連續且非空的一段使得這段和最大。
輸入資料:共兩行,第一行是資料個數n,第二行是序列
輸出資料:共一行,一個數:最大的和
樣例輸入
7
2 -4 3 -1 2 -4 3
樣例輸出
4
解釋:3 -1 2即為子段
資料範圍:n<=200000
看資料規模,複雜度最大不能超過nlogn,應該有O(n)的做法,下面給出O(n)的做法
觀察問題,發現有很強的階段性。
設num[i]為資料集(從0開始存),dp[i]的含義為以第i個元素結尾的子段的最大子段和,它就是階段。由於這個子段和只能與第(i-1)個元素結尾的子段和有關係,所以容易知道轉移方程為
dp[i]=num[0] (i==0)
=max(num[i],dp[i]+num[i]) (i>n)
即如果第i個元素如果接到前面的字串上不如自己自成一串,那就自成一串,否則加到前面上面去。
最後答案就是dp[i]中的最大值。
下面上程式碼:
#include<cstdio> #include<cstring> #include<algorithm> #include<climits> using namespace std; int n,ans; int num[200010]; int dp[200010]; int main(){ scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&num[i]); dp[0]=num[0]; for(int i=1;i<n;i++) dp[i]=max(num[i],num[i]+dp[i-1]); ans=-INT_MAX; for(int i=0;i<n;i++) ans=max(ans,dp[i]); printf("%d",ans); return 0; }
祝大家期末考試順利!
(黃老仙說這麼晚還看我直播,你一定考不好)