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...