AcWing1088 旅行問題 單調佇列DP

2021-10-07 07:33:25 字數 2024 閱讀 3182

題目傳送門

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

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

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

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

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

輸入格式

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

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

輸出格式

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

資料範圍

3≤n≤106

0≤pi≤2×109

0輸入樣例:

5

3 11 2

5 20 1

5 4

輸出樣例:
tak

nietak

nietak

題解:

環形路,擴充套件2倍變成一條路

先順時針方向:倒著求, 單調佇列存最小字首和, 最後判斷從 i 出發如果最小字首和s[j] >= s[ i ] (j > i, j > i + n - 1,且車站個數為n), 說明可以從i出發到各個點

逆時針方向: 正著求, 單調佇列存最大字首和, 最後判斷從 i 出發如果最大字首和s[j] <= s[ i ] (j < i, j > i - n - 1且車站個數為n), 說明可以從i出發到各個點

最後輸出答案即可

#include

using namespace std;

const

int n =

2e6+10;

typedef

long

long ll;

int st[n]

, l, r;

int vis[n]

;ll s[n]

;int a[n]

, b[n]

;int

main()

for(

int i =

1; i <=

2* n; i++

) s[i]

+= s[i -1]

; l =0;

r =-1

;for

(int i =

2* n; i >=

0; i--

)while

(l <= r && s[st[r]

]>= s[i]

)r--

; st[

++r]

= i;

}//翻轉一下,逆時針方向走

b[0]

= b[n]

;for

(int i =

1; i <= n; i++

) s[i]

= s[i + n]

= a[i]

- b[i -1]

;for

(int i =

1; i <=

2* n; i++

) s[i]

+= s[i -1]

; l =0;

r =-1

;for

(int i =

1; i <=

2* n; i++

)while

(l <= r && s[st[r]

]<= s[i]

)r--

; st[

++r]

= i;

}for

(int i =

1; i <= n; i++

)return0;

}

AcWing 108 奇數碼問題

題目描述 你一定玩過八數碼遊戲,它實際上是在乙個3 3的網格中進行的,1個空格和1 8這8個數字恰好不重不漏地分布在這3 3的網格中。例如 5 2 8 1 3 4 6 7在遊戲過程中,可以把空格與其上 下 左 右四個方向之一的數字交換 如果存在 例如在上例中,空格可與左 上 下面的數字交換,分別變成...

AcWing 108 奇數碼問題

原題鏈結 考察 歸併排序 n恒為奇數,所以左右上下移動不會改變逆序對的奇偶性.1 include 2 include 3 using namespace std 4const int n 250010 5 typedef long long ll 6 intn,a n b n tmp n 7void...

ACWING108 奇數碼問題(逆序對)

你一定玩過八數碼遊戲,它實際上是在乙個3 3的網格中進行的,1個空格和1 8這8個數字恰好不重不漏地分布在這3 3的網格中。例如 5 2 8 1 3 4 6 7 在遊戲過程中,可以把空格與其上 下 左 右四個方向之一的數字交換 如果存在 例如在上例中,空格可與左 上 下面的數字交換,分別變成 5 2...