Acwing 293 開車旅行 (倍增優化DP)

2022-09-16 08:51:12 字數 2529 閱讀 4126

小a和小b決定利用假期外出旅行,他們將想去的城市從1到n編號,且編號較小的城市在編號較大的城市的西邊,已知各個城市的海拔高度互不相同,記城市 i 的海拔高度為 hi。

城市 i 和城市 j 之間的距離 d[i,j] 恰好是這兩個城市海拔高度之差的絕對值,即 d[i,j]=|hi−hj|。

旅行過程中,小a和小b輪流開車,第一天小a開車,之後每天輪換一次。每個人每天均會從乙個城市出發走到另乙個城市。

他們計畫選擇乙個城市s作為起點,一直向東行駛,並且最多行駛x公里就結束旅行。

小a和小b的駕駛風格不同,小b總是沿著前進方向選擇乙個最近的城市作為目的地,而小a總是沿著前進方向選擇第二近的城市作為目的地(注意:本題中如果當前城市到兩個城市的距離相同,則認為離海拔低的那個城市更近)。

如果其中任何一人無法按照自己的原則選擇目的城市,或者到達目的地會使行駛的總距離超出x公里,他們就會結束旅行。

在啟程之前,小a想知道兩個問題:

1、對於乙個給定的 x=x0,從哪乙個城市出發,小a開車行駛的路程總數與小b行駛的路程總數的比值最小(如果小b的行駛路程為0,此時的比值可視為無窮大,且兩個無窮大視為相等)。如果從多個城市出發,小a開車行駛的路程總數與小b行駛的路程總數的比值都最小,則輸出海拔最高的那個城市。

2、對任意給定的 x=xi 和出發城市 si,求出小a開車行駛的路程總數以及小b行駛的路程總數。

輸入格式

第一行包含乙個整數 n,表示城市的數目。

第二行有 n 個整數,每兩個整數之間用乙個空格隔開,依次表示城市 1 到城市 n 的海拔高度,即 h1,h2,…,hn,且每個 hi 都是不同的。

第三行包含乙個整數 x0。

第四行為乙個整數 m,表示給定 m 組 si 和 xi。

接下來的 m 行,每行包含 2 個整數 si 和 xi,表示從城市 si 出發,最多行駛 xi 公里。

輸出格式

輸出共 m+1 行。

第一行包含乙個整數 s0,表示對於給定的 x0,從編號為 s0 的城市出發,小 a 開車行駛的路程總數與小 b 行駛的路程總數的比值最小。

接下來的 m 行,每行包含 2 個整數,之間用乙個空格隔開,依次表示在給定的 si 和 xi 下小 a 行駛的里程總數和小 b 行駛的里程總數。

資料範圍

1≤n≤105,

1≤m≤104,

−109≤hi≤109,

0≤x0≤109,

1≤si≤n,

0≤xi≤109,

資料保證hi互不相同。

輸入樣例:

104 5 6 1 2 3 7 8 9 10710

1 72 7

3 74 7

5 76 7

7 78 7

9 710 7

輸出樣例:

23 2

2 42 1

2 45 1

5 12 1

2 00 0

0 0好難的題目,qwq,首先我們如果選定了乙個城市作為起點,那麼我們接下來的ab行程將是唯一確定的,因為題目限制四了條件,相當於是乙個拓撲圖了,這個資訊我們可以預處理出來。然後我們還需要處理出從某個人從某個點開始走多少步數到達的城市,這裡我們就需要倍增優化了,因為資料是1e5,暴力列舉n方會超時。然後我們最後要處理的就是最後的dp陣列,表示某個人從某個點出發走i步數,所行駛的所有距離。

#include#include#include#include#include#include#include#include#includeusing namespace std;

#define rep(i,f_start,f_end) for (int i=f_start;i<=f_end;++i)

#define per(i,n,a) for (int i=n;i>=a;i--)

#define mt(x,i) memset(x,i,sizeof(x) )

#define rev(i,start,end) for (int i=start;ipii;

ll gcd (ll a,ll b)

inline int read()

while('0'<=ch&&ch<='9') return x*f;

}typedef pairplt;

const int maxn=100010,m=17;

const ll inf=1e12;

int n;

int h[maxn];

int ga[maxn],gb[maxn];

int f[m][maxn][2];

int da[m][maxn][2],db[m][maxn][2];

void init_g () ),s.insert ();

s.insert (),s.insert ();

per (i,n,1)

ll d1=inf,d2=inf;

int p1=0,p2=0;

per (k,3,0)

}cout

scanf ("%d",&m);

while (m--)

return 0;

}

NOIP2012 開車旅行 (倍增)

小 a 和小 b 決定利用假期外出旅行,他們將想去的城市從 1 到 n 編號,且編號較小的城市在編號較大的城市的西邊,已知各個城市的海拔高度互不相同,記城市 i 的海拔高度為hi,城市 i 和城市 j 之間的距離 d i,j 恰好是這兩個城市海拔高度之差的絕對值,即d i,j hi hj 旅行過程中...

倍增 luogu1081開車旅行

傳送門 倍增神題?細節超級多 其實思路很簡單 對於每個點,a和b要開去的目的地是固定的,所以就想到了倍增 開三個倍增陣列,t i j k 代表k從i開車走2 j天走到的那個城市 f是a走的路程,g是b走的路程 0代表a,1代表b 對於預處理,一開始怎麼想怎麼是n 2的 後來自己yy了一下覺得每次so...

開車旅行 巧妙的倍增 set

傳送門 對於找第一第二近,用set lower bound,預處理出nxt a nxt b 表示a,b下一步走到 然後倍增 st a i j 表示從i往後2 j步a走了多少 b同理 nxt i j 表示往後走2 j步的位置 類似lca那樣預處理就好了 一直re但對拍一小時後的偽ac include ...