發射站(單調佇列)

2022-06-08 11:54:09 字數 1061 閱讀 7540

某地有 \(n\) 個能量發射站排成一行,每個發射站 \(i\) 都有不相同的高度 \(h_i\),並能向兩邊(當然兩端的只能向一邊)同時發射能量值為 \(v_i\) 的能量,並且發出的能量只被兩邊最近的且比它高的發射站接收。

顯然,每個發射站發來的能量有可能被 \(0\) 或 \(1\) 或 \(2\) 個其他發射站所接受,出於安全考慮,每個發射站接收到的能量總和是我們很關心的問題。

由於資料很多,現在只需要你幫忙計算出接收最多能量的發射站接收的能量是多少。

\(1 \leq n \leq 1000000\)

因為是向兩邊發射能量,因此我們可以考慮將兩個方向分開考慮。因為兩個方向等價,所以我們只考慮向左發射的情形。

遍歷序列中的每乙個發射站,考慮它能接收到誰發出的能量。

因為本題肯定要採取\(o(n)\)複雜度的演算法,因此先對過程進行分析,尋求有用的性質。

考慮相鄰兩個發射站\(i, i + 1\),如果\(h_i < h_\),則\(i\)號發射站就不能接收到之後的能量了。

根據這條單調性,可以考慮使用單調佇列。如果當前發射站的高度大於隊尾發射站的高度,就將隊尾發射站出隊。這樣佇列中維護的就是高度遞減的發射站序列。

再考慮如何更新答案,佇列中的第\(i\)個發射站,只能將能量傳給\(i-1\)個發射站,因此每次入隊的時候更新一下前乙個的接收能量總和即可。

#include #include #include #include using namespace std;

const int n = 1000010;

int n;

int h[n], v[n];

int sum[n];

int q[n];

int main()

tt = 0; hh = 0;

for(int i = n; i >= 1; i --)

int res = 0;

for(int i = 1; i <= n; i ++) res = max(res, sum[i]);

printf("%d\n", res);

return 0;

}

洛谷 發射站 單調棧

題解 本題主要考查單調棧。簡要題意 乙個發射站會向左邊最近的比它高的和右邊比它高的其他發射站發射能量,求接收最多能量的發射站接收的能量是多少。1.單調棧 維護乙個單調遞增的棧,如果準備入棧的元素大於棧頂元素,那麼新元素能量加上棧頂元素能量,退棧。如下 include include includeu...

P1901 發射站 單調棧

題目描述 某地有 n 個能量發射站排成一行,每個發射站 i 都有不相同的高度 hi,並能向兩邊 當 然兩端的只能向一邊 同時發射能量值為 vi 的能量,並且發出的能量只被兩邊最近的且比 它高的發射站接收。顯然,每個發射站發來的能量有可能被 0 或 1 或 2 個其他發射站所接受,特別是為了安 全,每...

P1901 發射站(單調棧)

假設當前有 a 1 7 a 2 5 a 3 4 三個發射塔,現在在後面加乙個發射塔,高度為 a 4 6a 4 要接受 a 3 a 2 這兩個發射塔的訊號,以及將自身的訊號發射給 a 1 很明顯利用單調棧,將 a 3 出棧,再將 a 2 出棧,最後棧內只剩下 a 1 a 4 最後統計每乙個位置處的能量...