noip2011 公交觀光

2022-06-02 10:09:11 字數 2507 閱讀 8524

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

設共有m個遊客,每位遊客需要乘車1次從乙個景點到達另乙個景點,第i位遊客在ti分鐘來到景點ai,希望乘車前往景點bi(ai乙個乘客的旅行時間,等於他到達目的地的時刻減去他來到出發地的時刻。因為只有一輛觀光車,有時候還要停下來等其他乘客,乘客們紛紛抱怨旅行時間太長了。於是聰明的司機zz給公交車安裝了k個氮氣加速器,每使用乙個加速器,可以使其中乙個di減1。對於同乙個di可以重複使用加速器,但是必須保證使用後di大於等於0。

那麼zz該如何安排使用加速器,才能使所有乘客的旅行時間總和最小?

第1行是3個整數n, m, k,每兩個整數之間用乙個空格隔開。分別表示景點數、乘客數和氮氣加速器個數。

第2行是n-1個整數,每兩個整數之間用乙個空格隔開,第i個數表示從第i個景點開往第i+1個景點所需要的時間,即di。

第3行至m+2行每行3個整數ti, ai, bi,每兩個整數之間用乙個空格隔開。第i+2行表示第i位乘客來到出發景點的時刻,出發的景點編號和到達的景點編號。

共一行,包含乙個整數,表示最小的總旅行時間。

樣例說明:

對d2使用2個加速器,從2號景點到3號景點時間變為2分鐘。

公交車在第1分鐘從1號景點出發,第2分鐘到達2號景點,第5分鐘從2號景點出發,第7分鐘到達3號景點。

第1個旅客旅行時間7 - 0 = 7分鐘;

第2個旅客旅行時間2 - 1 = 1分鐘;

第3個旅客旅行時間7 - 5 = 2分鐘。

總時間7 + 1 + 2 = 10分鐘。

資料範圍:

對於10%的資料,k = 0;

對於20%的資料,k = 1;

對於40%的資料,2 ≤ n ≤ 50,1 ≤ m ≤ 1,000,0 ≤ k ≤ 20,0 ≤ di ≤ 10,0 ≤ ti ≤ 500;

對於60%的資料,1 ≤ n ≤ 100,1 ≤ m ≤ 1,000,0 ≤ k ≤ 100,0 ≤ di ≤ 100,0 ≤ ti ≤ 10,000;

對於100%的資料,1 ≤ n ≤ 1,000,1 ≤ m ≤ 10,000,0 ≤ k ≤ 100,000,0 ≤ di ≤ 100,0 ≤ ti ≤ 100,000。

正解=貪心

設 time[i] 為到達第 i 的時間,

設 last[i] 為出現在第 i 點的最後乙個遊客的時間,

題目求所有乘客等待時間和,即ans=(time[b[i]]-t[i])(1<=i<=m)

t[i]為定值,那應使time的值盡量小。

顯然time[i]=max(time[i-1],last[i-1])+d[i-1];

由於使用乙個加速器後可能會是多個time減少,

last[i]則就成為了乙個限制條件(使time[i]的減少無意義),

在一條路徑使用加速器後會對後面多個time(不是所有)產生影響,

設在 i 放乙個加速器可影響到的點數的數量為f[i],

設 sum 為記錄在 i 之前及 i 已下車的人數, 

則如果在i點使用加速器後,可影響的人數為sum[f[i]+i]-sum[i],

也就是在 i 到 f[i]+i 之間要到達下乙個點的人數

便可以此貪心,

每使用一次加速器後(減少d),重新再算 time 和 f,在從中選出sum[f[i]+i]-sum[i]中最大的,在 i 用加速器

ps. 100000*1000的複雜度居然能過- =

**如下:

1 #include2 #include3 #include4 #include

5 #include6 #include7

#define inf 999999999999

8#define ll long long

9#define max(x,y) if(y>x) x=y;

10#define n 10010

11//

using namespace std ;

12int

f[n],sum[n],dis[n],up[n],down[n],b[n],last[n],time[n];

13int

n,m,k,total,ans;

14int max(int a,int

c)17

intmain()

29while(k--)

45if(maxpos) --dis[maxpos]; 46}

47for(int i=2;i<=n;i++)

48 time[i]=max(time[i-1],last[i-1])+dis[i-1

];49

for(int i=1;i<=m;i++) ans+=time[b[i]];

50 printf("

%d",ans-total);

51 }

view code

NOIP2011 觀光公交

題目 分析 設last i 表示來到第i個景點的乘客最晚的時間,time i 表示車到達第i個景點的最小時間。因為每個乘客到達的時間已經固定,所以要使總時間最小,就是使 time down i 最小,其中down i 代表每位乘客的目的地。先考慮不用加速器的情況。可以直接遞推求出答案,time i ...

NOIP2011 觀光公交

傳送門 luogu 有點麻煩,幸好 o n 2 能過。貪心地想一想,我們如果要用加速器,肯定是要選擇車上人數最多的時段加速。但是我們就會面臨這樣的情況 那麼我們就分類討論一下,預處理一些東西 每個站的下車人數,需要更新的車到站時間,每個站的最後乙個下車人數。然後隨便搞一下就好了。include in...

NOIP2011 觀光公交

這是乙個貪心,說實話開始做的時候.完全沒看出來qaq。首先對於每個點當然是能走就走,不能走就等待,這是無法控制的。所以只考慮氮氣加速器加在 可以使時間總和盡量少。如果選擇加速,可能會使後面等待的時間更長,或者更短,對後面都會有影響。但是沿著一條邊加速會影響後面的所有邊麼?這可不一定 來來來,我們分類...