P1315 觀光公交

2022-03-04 20:57:55 字數 2971 閱讀 2982

風景迷人的小城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該如何安排使用加速器,才能使所有乘客的旅行時間總和最小?

輸入格式:

輸入檔名為bus.in。

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

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

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

輸出格式:

輸出檔名為bus.out。共一行,包含乙個整數,表示最小的總旅行時間。

輸入樣例#1:

3 3 2

1 40 1 3

1 1 2

5 2 3

輸出樣例#1:

10

【輸入輸出樣例說明】

對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 ≤ t i ≤ 500;

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

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

noip2011提高組day2第3題

solution:

本題直接貪心+模擬是可以過的。

考慮這樣去貪心:

1、每次加速器的使用,要使得總等待時間減小的盡可能多,則必須在車上人數最多的某條路上使用最優。

2、若當前的路上使用了加速器後到達了某個點時,依然要等待某人,則沒必要在當前路上使用加速器(用了顯然等同於浪費,到當前點還是得等到人上車才能走,每人等待時間並沒有減少)。

於是我們直接模擬(注意區別時間和時刻):

設t[i]表示i到i+1兩點的原始行駛時間,last[i]表示最後乙個從i點出發的人的時刻,arrt[i]表示最終從i點出發的時刻,off[i]表示到i點下車的人數,cut[i]表示i到i+1兩點間最多能減少的時間,a[i].t表示第i個人的出發時刻,a[i].s表示第i個人出發起點,a[i].e表示第i個人要到的終點。

模擬使用每個加速器的過程,每次選擇滿足性質2且當前車上人數最多的路線。

注意一些細節,比如:1、當前路的減少的時間顯然不能超過原始行駛時間。  2、若到達某個點的時刻大於最後乙個從i點上車的時刻,則當前路上減小的最多時間等於到第i個點下車的人數和到i+1點下車的人數和。   3、當不存在可以再減小的時間時直接跳出列舉。

最後累加每個人的到達時間就ok了。最壞時間複雜度o(kn)。

**:

#include#define il inline 

#define ll long long

#define debug printf("%d %s\n",__line__,__function__)

using

namespace

std;

int ans,n,m,k,t[10005],last[10005],arrt[10005],off[10005],cut[10005

];struct

peoplea[

10005

];int

main()

for(int i=1;i<=n;i++)arrt[i]=max(arrt[i-1],last[i-1])+t[i-1

];

while(k--)

int maxt=0,now=0

;

for(int i=1;i)

if(cut[i]>maxt)maxt=cut[i],now=i;

if(!now)break

; t[now]--;

for(int i=now+1;i<=n;i++)arrt[i]=max(arrt[i-1],last[i-1])+t[i-1

]; }

for(int i=1;i<=m;i++)ans+=arrt[a[i].e]-a[i].t;

cout

}

洛谷P1315 觀光公交

題目 模擬 貪心 一開始看到10 5的資料,以為要klogn就敲了個線段樹上去 結果沒考慮後效性,只過了3個點 正解 一開始先處理出每一站的到站時間是對的,而隨著修改到站時間的改變不一定滿足字首關係 假設在某一站有人很晚才出發,那不管先前改變了多少後面的到站時間都是不變的 綜上 還需要維護修改一段距...

洛谷P1315 觀光公交

題目 如果沒有氮氣加速器,則該題為乙個模擬題。但是本題存在氮氣加速器,所以我們需要考慮貪心策略。題目要求我們使所有人等待的時間最短,因此我們需要算出每段路徑 路徑即為車站之間的 d 對時間的貢獻多少,取其中最多的減去就好了。首先我們需要求出每個車站最遠向右影響到什麼地方,然後算出這段地方的影響總人數...

洛谷P1315 觀光公交

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