acwing 135. 最大子序和
大佬講解(原題解鏈結見文末)
單調佇列 o(n)
首先單調佇列,不同一般的佇列,他需要的stl是deque
雙端佇列,因為我們要支援隊頭插入和隊尾插入.
單調佇列做法大致如下:首先我們需要找到單調性,這道題目的顯而易見.我們知道區間和的做法,一般都是字首和,而字首和的求法就是s[r]−s[l−1],l和r均為左端點和右端點.
然後我們接著思考,既然如此如果說我們確定了右端點,那麼左端點可以取的點,是不是也存在乙個區間[a,b],然後這個區間就是我們的決策區間,接著我們思考如何優化這個決策區間.
優化這個區間,首先我們得找出兩個點,設i點為列舉的右端點,j點為決策區間內的一點,k點也為決策區間內的一點.則不妨設k≤j≤i 且 s[k]≤s[j].
接著我們發現,如果說k點和j點都滿足條件的話,那麼明顯j點更加優秀,因為s[j]點值又小,答案s[i]−s[j]
肯定比s[i]−s[j]越大,而且j點還在k點前,也就是lyd老師所說的生存能力更加優秀.
總的來說我們就已經確定好了單調性,既然如此的話,那麼我們就可以開始單調佇列了.
**
#include #include #include using namespace std;
#define ll long long
const int n = 300005;
ll s[n];
dequeq;
int main()
ll ans = -n;
q.push_back(0);
//剛開始佇列中沒有數 呼叫 q.front 可能會出事 先丟個0進去
//後面呼叫 front 時佇列中一定有值(插入 i 的時候 i-1 一定在)
for(int i = 1; i <= n; ++i)
ans = max(ans, s[i] - s[q.front()]);
//沒有加個 0 的話 第一次可能返回乙個很大的值 - > 陣列越界
while(q.size() && s[q.back()] >= s[i])
q.push_back(i);
} printf("%lld\n", ans);
return 0;
}
最後哪位知道隊列為空的時候 front 到底返回什麼qaq Acwing135 最大子序和
輸入乙個長度為n的整數序列,從中找出一段長度不超過m的連續子串行,使得子串行中所有數的和最大。注意 子串行的長度至少是1。輸入格式 第一行輸入兩個整數n,m。第二行輸入n個數,代表長度為n的整數序列。同一行數之間用空格隔開。輸出格式 輸出乙個整數,代表該序列的最大子序和。資料範圍 1 n,m 300...
AcWing 135 最大子序和
輸入乙個長度為n的整數序列,從中找出一段長度不超過m的連續子串行,使得子串行中所有數的和最大。注意 子串行的長度至少是1。輸入格式 第一行輸入兩個整數n,m。第二行輸入n個數,代表長度為n的整數序列。同一行數之間用空格隔開。輸出格式 輸出乙個整數,代表該序列的最大子序和。資料範圍 1 n,m 300...
AcWing135 最大子序和
link 陣列沒開夠,爆零兩行淚 longlong開成int,爆零兩行淚 多組忘清空,爆零兩行淚 dp 沒初值,爆零兩行淚 深搜沒邊界,爆零兩行淚 廣搜忘出隊,爆零兩行淚 輸入沒加 爆零兩行淚 模數沒看見,爆零兩行淚 1 不輸出,爆零兩行淚 越界不特判,爆零兩行淚 線段樹開一倍,爆零兩行淚 無向變有...