單調佇列優化DP 旅行問題

2021-10-02 06:03:28 字數 1909 閱讀 8950

john 打算駕駛一輛汽車周遊乙個環形公路。

公路上總共有 n 個車站,每站都有若干公升汽油(有的站可能油量為零),每公升油可以讓汽車行駛一千公尺。

john 必須從某個車站出發,一直按順時針(或逆時針)方向走遍所有的車站,並回到起點。

在一開始的時候,汽車內油量為零,john 每到乙個車站就把該站所有的油都帶上(起點站亦是如此),行駛過程中不能出現沒有油的情況。

任務:判斷以每個車站為起點能否按條件成功周遊一周。

輸入格式

第一行是乙個整數 n,表示環形公路上的車站數;

接下來 n 行,每行兩個整數 pi,di,分別表示表示第 i 號車站的存油量和第 i 號車站到下一站的距離。

輸出格式

輸出共 n 行,如果從第 i 號車站出發,一直按順時針(或逆時針)方向行駛,能夠成功周遊一圈,則在第 i 行輸出 tak,否則輸出 nie。

資料範圍

3 ≤n

≤106

3≤n≤10^6

3≤n≤10

6,0 ≤p

i≤2×

10

90≤p_i≤2×10^9

0≤pi​≤

2×10

9,0

≤2×1

09

00​≤2×

109輸入樣例:

53 1

1 25 2

0 15 4

輸出樣例:

taknie

taknie

tak我們首先分析一下題意,他說從任意乙個加油站出發,然後順時針或者逆時針繞一圈可以回來就行。我們根據線性dp的學習可以知道任何環形問題都可以轉換為乙個線性的問題。只需要在後面加乙個n的長度就可以了,然後我們可以知道他要求的就是固定長度為n的區間最值問題。如果我們區間為n的最小字首和都大於0的話代表我們是可以完成的。所以看到固定長度我們就想到了單調佇列了。所以我們這道題用單調佇列維護乙個順時針和乙個逆時針就可以了,需要注意的時候順時針維護的時候我們需要先更新我們的隊尾,所以while放在了前面,並且我們這個時候是端點必須小於i-n,是不包含當前點的,而我們逆時針是包含的,並且我們不需要先更新隊尾。

#include

#define int long long

#define lowbit(x) (x&(-x))

using

namespace std;

const

int n=

1e6+6;

int p[n]

,d[n]

,s[n*2+

5],q[n*2]

,ans[n*2]

;signed

main()

} hh=

0,tt=-1

; d[0]

=d[n]

;for

(int i=

1;i<=n;i++

) s[i]

=s[i+n]

=p[i]

-d[i-1]

;for

(int i=

1;i<=n*

2;i++

) s[i]

+=s[i-1]

;for

(int i=

1;i<=

2*n;i++

)while

(hh<=tt&&s[q[tt]

]<=s[i]

) tt--

; q[

++tt]

=i;}

for(

int i=

1;i<=n;i++)if

(ans[i]

)puts

("tak");

else

puts

("nie");

}

旅行問題(單調佇列優化)

john 打算駕駛一輛汽車周遊乙個環形公路。公路上總共有 n 個車站,每站都有若干公升汽油 有的站可能油量為零 每公升油可以讓汽車行駛一千公尺。john 必須從某個車站出發,一直按順時針 或逆時針 方向走遍所有的車站,並回到起點。在一開始的時候,汽車內油量為零,john 每到乙個車站就把該站所有的油...

單調佇列 旅行問題

描述 john 打算駕駛一輛汽車周遊乙個環形公路。公路上總共有 n 車站,每站都有若干公升汽油 有的站可能油量為零 每公升油可以讓汽車行駛一千公尺。john 必須從某個車站出發,一直按順時針 或逆時針 方向走遍所有的車站,並回到起點。在一開始的時候,汽車內油量為零,john 每到乙個車站就把該站所有...

單調佇列優化DP問題總結

小結 可見合理的使用哨兵可以簡化對邊界條件的處理 在單調佇列中使用哨兵,主要是在第1個列舉到的數,它依賴的滑動視窗此時為空,無法獲取到head,那麼此時的處理邏輯是什麼樣呢?一般來講從兩個方面來考慮 1 是不是視窗長度越界,需要出隊首元素?while hh tt q hh i m hh 這種情況下,...