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=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)|)
a[i]+a
[j]+
min(
∣i−j
∣,∣n
−(i−
j)∣)
。也就是環上順時針和逆時針的距離的最小值。現在變成了鏈,就要發生改變。
很容易發現,順時針和逆時針的最小值就是看看∣i−
j∣
|i-j|
∣i−j
∣是否超過了n/2
n/2n/
2,如果沒有超過,那麼肯定順時針更優,否則逆時針更優。
那麼將環拆成鏈之後,順時針還是在原來的環上(即i,j
≤n
i,j\leq n
i,j≤
n),就可以直接求出答案。否則j
jj就會超過nnn。
如果是逆時針,那麼鏈拷貝乙份的作用求起到了。那麼我們用∣i−
j∣
|i-j|
∣i−j
∣變成∣j−
i∣
|j-i|
∣j−i
∣,之後又知道j=j
+n
j=j+n
j=j+
n,那麼就有∣i−
j∣=∣
j−i∣
=∣j+
n−i∣
|i-j|=|j-i|=|j+n-i|
∣i−j∣=
∣j−i
∣=∣j
+n−i
∣。那麼也變成了一條鏈。就可以求出答案了。時間複雜度o(n
2)
o(n^2)
o(n2)。
必須優化。我們發現要求最大值,那麼就可以用單調佇列優化,維護在區間範圍內的最大值,每次至直接o(1
)o(1)
o(1)
求最大值即可。
時間複雜度o(n
)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 單調佇列
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就可以...
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...