佇列_單調佇列_CH1201_最大子序和
阿新 • • 發佈:2018-12-19
思路分析:
這是一道典型的單調佇列應用問題, 先給出AC程式碼, 然後給出程式正確性證明和時間複雜度分析.
//CH1201_最大子序和 #include <cstdio> #include <algorithm> #include <deque> using namespace std; const int MAXN = 3e5 + 5; const long long NIL = 1e18; long long psum[MAXN];//字首和陣列 int main(){ int n, m; scanf("%d %d", &n, &m); for(int i = 1; i <= n; ++i) scanf("%lld", &psum[i]), psum[i] += psum[i - 1]; deque<int> de(1, 1); long long ans = psum[1]; for(int i = 2; i <= n; ++i){ if(de[0] < i - m) de.pop_front(); ans = max(ans, psum[i] - psum[de[0]]); while(!de.empty() && psum[de.back()] >= psum[i]) de.pop_back(); de.push_back(i); } printf("%lld\n", ans); }
(1)程式正確性證明:
設輸入序列為,考慮證明 每次第12至17行迴圈頭檢測之前均有ans = max{完全位於的非空連續子段的和}, 且滿足i > k >= i - m, 最小的psum[k]對應的最大k值在佇列de中, 顯然當i = 2時該結論成立. 假設當i <= b 時該結論成立, 對於i = b + 1, 分兩種情況考慮, 如果滿足b + 1 > k >= b + 1 - m, 最小的psum[k]對應的最大k值與滿足b > k >= b - m, 最小的psum[k]對應的最大k值相同, 那麼上述結論顯然成立, 如果滿足b + 1 > k >= b + 1 - m, 最小的psum[k]對應的最大k值比滿足b > k >= b - m ,最小的psum[k]對應的最大k值大, 設該值為q, 考慮對於i為q...b時程式的執行情況, 顯然min{
(2)時間複雜度分析:
對於第12至17行的迴圈, 每個元素至多入佇列de一次和出佇列一次, 因此該程式的時間複雜度為O(n)