luogu1315 觀光公交

2022-06-30 08:09:08 字數 2214 閱讀 7846

乙個公交車在一條線上從1站、2站走到n站,站站間有距離。另有m個乘客在時間點t在a站等候要到b站。對於乙個站,如果車比人早到,則車等人,如果人比車早到,則人等車(我一開始做題時把這個情況當作已知不可能發生了55555)。另外有d個空間瞬移器,使得汽車在0秒內前進乙個單位距離。站與站間可重複用空間瞬移器,但用兩站間使用空間瞬移器的數量不多於兩站間距離。現在要求對空間瞬移器進行最優安排,使得所有乘客等車+在車上的時間和最小,輸出這個最小值。

如果不使用加速器,那麼汽車的時間安排肯定是在每個站點接到最後乙個乘客後直接出發,否則浪費那時間幹什麼呢?

我們的入手點在於:在當前的形式下(用了加速器相當於兩站點間的距離減少一,變成了同乙個問題),我們要把當前的加速器用到哪一段路上。不要只想乙個情況!以下將在乙個站點最後乙個開始等候的人簡稱為「人」。

在不使用加速器的情況下,所有站點都是車等人:如果在a站到b站間使用加速器,只有在b站下車的人被影響。因此我們在與前一站仍有距離的站中選擇在此站下車的人最多的站的之前的路段使用加速器。

在不使用加速器的情況下,所有站點都是人等車:我們要在最一開始的路段上使用加速器,因為這樣整條路上所有人的時間都會減少1。

1沒有什麼思路;但2有。如果站a、b為兩個車等人的站,那麼如果在站a和a+1之間使用加速器,則在[a+1,b]站下車的人的時間都會減少1!

因此我們根據當前車等人的站將整個路段拆分成幾個區間,我們每次都選出下車人最多的區間(統計下車人可以使用字首和)(動態選出最多可以使用優先佇列)。將其在一開始加速(意味著區間內所有站點車的到達時間(出發時間(人等車時,出發時間和))都-1)後,將該區間由人等車變為人車同時到的站點拆分成子區間再次加入佇列,直到加速器用完為止。

提前把一些定義下好了,可以節省大量時間。如:

特殊的是終點,因為其肯定沒有人等車了。那麼此時「最後乙個人在此站點等候的時間」必須要設為無窮大,否則其被認為是有乙個人在0時間在最後乙個站點等候,這就錯了。

明確一點:距離為0的影響在於,對於乙個全部都是人等車的區間,如果該區間的左端點之前的距離為0,則該區間不能被加速。(如果乙個prevdist==0的站點之前是人等車的站,此時照常處理,所以不要在加速時assert(區間中當前節點的prevdist>0))而只有當左端點為初始態或被更改時(得到乙個子區間[l,r],然後l=r+1)才有可能遇到上述情況,而此時r必然等於l。因此如果區間l的prevdist==0,則l跳過(l++),r隨之更改(r++)。

#include #include #include #include #include #include using namespace std;

const int max_pass = 10010, max_stat = 1010, inf = 0x3f3f3f3f;

int totstat, totpass, totacc;

int offpassprefix[max_stat];

struct stat

_stats[max_stat];

struct pass

pass(){}

}_passes[max_pass];

struct range

bool operator < (const range& a) const

void getaccablesubranges(void(*func) (range))

else if (_stats[r].intime <= _stats[r].lastpasstime)

}} void accelerate()//accelerate at left prev.

_stats[r].intime--;

_stats[l].prevdist--;

totacc--;

}};void read()

}void init()

for (int i = 2; i <= totstat; i++)

_stats[totstat].lastpasstime = inf;

for (int i = 1; i <= totstat; i++)

offpassprefix[i] = _stats[i].offpasscnt + offpassprefix[i - 1];

}priority_queueq;

void inq(range r)

void doacc()

}int getans()

int main()

P1315 觀光公交

風景迷人的小城y 市,擁有n 個美麗的景點。由於慕名而來的遊客越來越多,y 市特意安排了一輛觀光公交車,為遊客提供更便捷的交通服務。觀光公交車在第 0 分鐘出現在 1號景點,隨後依次前往 2 3 4 n 號景點。從第 i 號景點開到第 i 1 號景點需要 di 分鐘。任意時刻,公交車只能往前開,或在...

luogu P1315 觀光公交

比較難的貪心!預處理很多東西,另外,寫注釋好像有點用!可能是心理作用?反正還是寫得挺順利的?include include define ri register int define u int namespace opt while s 0 s 9 return x f using opt in ...

LUOGU P1315 觀光公交 貪心

傳送門 首先我們要把加速器乙個乙個的用,用在什麼地方呢。假設當前站車比人晚到,那麼車上的人與等待的人都會受到影響 否則的話只有在當前站下車的人有影響。我們第一步先求出車到站的時間,對於一條路來說,如果人等車,那麼在這條路用加速器的效果可以繼續向後延伸。否則只會對下一站造成影響。這樣的話維護乙個陣列 ...