動態規劃 最大子段和
阿新 • • 發佈:2019-03-20
mes 最小 最大的 iostream ace 動態規劃 strong 最大值 ffffff
子段與子段和的概念:
給定一個由數字組成的序列,其中一段連續的序列稱為一個子段(假設非空),子段中所有的數字和就是為 子段和
例子:
{1,2,3,4} ,
子段有 {1} {1,2} {1,2,3} {1,2,3,4} {2,3} {2,3,4} {3,4} {4}
O(n2) 枚舉的做法:
for(int i=0;i<n;++i){ long sum = 0; for(int j=i;j<n;++j){ sum += a[j]; if(sum > nMax){ nMax= sum; } } }
通過觀察發現。
(1) 整個序列都是負數,那麽 最大子段和 為 最小的負數 。
(2) 如果都是正數,那麽 最大子段和 就是 整個序列的的和。
(3) 如果有正有負,那麽 最大的子段和 >= 整個序列的最大值,
那麽我們可以假設一個變量sum = 0; 來記錄當前的子段和。
ans 記為 整個序列的最大值
因為要得到最大的子段 假設{ n1,n2,n3 },那麽這個子段前綴 {n1,n2} 一定不會 < 0
要得到 更大的子段和,我們就不會用 < 0 的子段和 來 拖累 後面的子段和。
用 ans = max(ans , sum)。來求出結果
O(n) 動態規劃實現代碼:
#include <iostream> #include <algorithm> using namespace std; const int inf = 0x7fffffff; int num[101]; int main() { int N; cin >> N; for(int i=0;i<N;i++){ cin >> num[i]; } intans = -inf; for(int i=0;i<N;i++){ ans = max(ans,num[i]); } if(ans <= 0){ cout << ans << endl; }else{ int sum =0; for(int i=0;i<N;i++){ if(sum + num[i] < 0){ sum = 0; }else{ sum += num[i]; } ans = max(ans,sum); } cout << ans << endl; } return 0; }
動態規劃 最大子段和