CH 5501 環路運輸 DP 單調佇列

2022-09-03 05:24:09 字數 1510 閱讀 2813

nn

個在乙個環上的倉庫,兩兩之間運貨的代價是a[i

]+a[

j]+m

in(∣

i−j∣

,∣n−

(i−j

)∣)a

[i]+

a[j]

+min

(∣i−

j∣,∣

n−(i

−j)∣

)求最大代價。

環上的dp固然不好做,可以先把環拆成鏈,再拷貝乙份。成為一條長度為2n2

n的鏈。

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

那麼接下來的dp就再鏈上dp就可以了。

首先對於兩點的距離,取的是a[i

]+a[

j]+m

in(∣

i−j∣

,∣n−

(i−j

)∣)a

[i]+

a[j]

+min

(∣i−

j∣,∣

n−(i

−j)∣

)。也就是環上順時針和逆時針的距離的最小值。現在變成了鏈,就要發生改變。

很容易發現,順時針和逆時針的最小值就是看看∣i−

j∣∣i

−j∣是否超過了n/2

n/2,如果沒有超過,那麼肯定順時針更優,否則逆時針更優。

那麼將環拆成鏈之後,順時針還是在原來的環上(即i,j

≤ni,

j≤n),就可以直接求出答案。否則j

j就會超過nn。

如果是逆時針,那麼鏈拷貝乙份的作用求起到了。那麼我們用∣i−

j∣∣i

−j∣變成∣j−

i∣∣j

−i∣,之後又知道j=j

+nj=

j+n,那麼就有∣i−

j∣=∣

j−i∣

=∣j+

n−i∣

∣i−j

∣=∣j

−i∣=

∣j+n

−i∣。那麼也變成了一條鏈。就可以求出答案了。時間複雜度o(n

2)o(

n2)。

必須優化。我們發現要求最大值,那麼就可以用單調佇列優化,維護在區間範圍內的最大值,每次至直接o(1

)o(1

)求最大值即可。

時間複雜度o(n

)o(n

)

#include

#include

#include

using

namespace std;

int n,ans,a[

2000011];

deque<

int> q;

intmain()

for(

int i=n+

1;i<=n+n;i++

)//從n+1開始找

printf

("%d\n"

,ans)

;return0;

}

CH 5501 環路運輸 DP 單調佇列

n nn個在乙個環上的倉庫,兩兩之間運貨的代價是a i a j m in i j n i j a i a j min i j n i j a i a j min i j n i j 求最大代價。環上的dp固然不好做,可以先把環拆成鏈,再拷貝乙份。成為一條長度為2n2n 2n的鏈。for int i ...

CH5501 環路運輸 環形 單調佇列

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

Ch5501 環路運輸 環形處理dp

有n座倉庫,然後是乙個環,兩個倉庫之間的運輸距離為ai aj dis i,j a i aj d is i j dis i,j mi n i j n i j d is i,j mi n i j n i j 我們將a複製乙份放在原陣列後面,然後就變成了2 n的線性。然後我們列舉i,之後i和j的距離為ai...