環路運輸 環形結構 單調佇列(滑動視窗)

2021-10-05 13:51:24 字數 1383 閱讀 5466

在一條環形公路旁均勻地分布著n座倉庫,編號為1~n,編號為 i 的倉庫與編號為 j 的倉庫之間的距離定義為 dist(i,j)=min⁡(|i-j|,n-|i-j|),也就是逆時針或順時針從 i 到 j 中較近的一種。

每座倉庫都存有貨物,其中編號為 i 的倉庫庫存量為 ai。

在 i 和 j 兩座倉庫之間運送貨物需要的代價為 ai+aj+dist(i,j)。

求在哪兩座倉庫之間運送貨物需要的代價最大。

輸入格式

第一行包含乙個整數n。

第二行包含n個整數a1~an。

輸出格式

輸出乙個整數,表示最大代價。

資料範圍

1≤n≤106,

1≤ai≤107

輸入樣例:

5

1 8 6 2 5

輸出樣例:

15
思路:從n個點中任選兩個點,然後再計算其代價,時間複雜度是n^2的,因此,需要優化找最大代價的時間。

首先,這裡是乙個環形結構,可以用破環成鏈的方法:先將這個環從頭到尾展開,然後再接上相同的一段,變成2*n長度,這樣就可以列舉任意起點開始的任意長度了。

其次,因為每一段距離在列舉時具有對稱性(正向求和反向求是一樣的),所以只需要按乙個方向列舉乙個點(終點j)前面[0,n/2]長度範圍的另乙個點(起點i),然後計算每個起點和當前列舉的固定點(終點)的代價,取其中的最大值,再取所有固定終點的最大值方案中的最大值即可,可以發現每次都是取乙個點(終點)前面[0,n/2]長度範圍最大代價,可以用單調佇列中經典的滑動視窗問題來維護這段區間的最大代價:w[i]+w[j]+j-i ,因為j和w[j]再列舉時時固定的,所以維護w[i]-i的最大值即可。

注:單調佇列維護最大值,所以每次i前面小於i的代價的值都不會作為最大值(因為已經有比其大的i了),所以可以將i前面小於i的代價的值都刪掉,從而維護佇列的單調遞減性,保證每次隊頭即為最大。

完整**:

#include #include #include using namespace std;

const int maxn=2e6+7;

int w[maxn],q[maxn],n;

int main()

//滑動視窗維護當前i和在i前面且與j相隔len長度的i兩點的代價的最大值(j是固定的,即求max(w[i]-i):

int hh=0,tt=-1;

int len=n/2,res=0;

for(int i=1;i<=n*2;i++)

cout

}

環路運輸 (單調佇列 環形處理)

題目描述 在一條環形公路旁均勻地分布著n座倉庫,編號為1 n,編號為 i 的倉庫與編號為 j 的倉庫之間的距離定義為 dist i,j min i j n i j 也就是逆時針或順時針從 i 到 j 中較近的一種。每座倉庫都存有貨物,其中編號為 i 的倉庫庫存量為 ai。在 i 和 j 兩座倉庫之間...

CH5501 環路運輸 環形 單調佇列

ch description 在一條環形公路旁均勻地分布著n座倉庫,編號為1 n,編號為 i 的倉庫與編號為 j 的倉庫之間的距離定義為 dist i,j min i j n i j 也就是逆時針或順時針從 i 到 j 中較近的一種.每座倉庫都存有貨物,其中編號為 i 的倉庫庫存量為 ai.在 i ...

滑動窗空 單調佇列

給定乙個大小為n 106的陣列。有乙個大小為k的滑動視窗,它從陣列的最左邊移動到最右邊。您只能在視窗中看到k個數字。每次滑動視窗向右移動乙個位置。以下是乙個例子 該陣列為 1 3 1 3 5 3 6 7 k為3。您的任務是確定滑動視窗位於每個位置時,視窗中的最大值和最小值。輸入格式 輸入包含兩行。第...