WikiOI 1139 觀光公交 (NOIP2011) 貪心

題目描述 Description
風景迷人的小城 Y 市,擁有n 個美麗的景點。由於慕名而來的遊客越來越多,Y 市特意安排了一輛觀光公交車,爲遊客提供更便捷的交通服務。觀光公交車在第0 分鐘出現在1號景點,隨後依次前往2、3、4……n 號景點。從第i 號景點開到第i+1 號景點需要Di 分鐘。任意時刻,公交車只能往前開,或在景點處等待。
設共有 m 個遊客,每位遊客需要乘車1 次從一個景點到達另一個景點,第i 位遊客在Ti 分鐘來到景點Ai,希望乘車前往景點Bi(Bi>Ai)。爲了使所有乘客都能順利到達目的地,公交車在每站都必須等待需要從該景點出發的所有乘客都上車後才能出發開往下一景點。
假設乘客上下車不需要時間。
一個乘客的旅行時間,等於他到達目的地的時刻減去他來到出發地的時刻。因爲只有一輛觀光車,有時候還要停下來等其他乘客,乘客們紛紛抱怨旅行時間太長了。於是聰明的司機ZZ 給公交車安裝了k 個氮氣加速器,每使用一個加速器,可以使其中一個Di 減1。對於同一個Di 可以重複使用加速器,但是必須保證使用後Di 大於等於0。

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

輸入描述 Input Description
第 1 行是3 個整數n, m, k,每兩個整數之間用一個空格隔開。分別表示景點數、乘客數和氮氣加速器個數。
第 2 行是n-1 個整數,每兩個整數之間用一個空格隔開,第i 個數表示從第i 個景點開往第i+1 個景點所需要的時間,即Di。
第 3 行至m+2 行每行3 個整數Ti, Ai, Bi,每兩個整數之間用一個空格隔開。第i+2 行表示第i 位乘客來到出發景點的時刻,出發的景點編號和到達的景點編號。

輸出描述 Output Description
共一行,包含一個整數,表示最小的總旅行時間。

樣例輸入 Sample Input
3 3 2
1 4
0 1 3
1 1 2
5 2 3

樣例輸出 Sample Output
10

數據範圍及提示 Data Size & Hint
對 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。

program mys;
var i,j,m,n,k,l,ans,max1,xx,tt:longint;
st,start,c,s,d:array[0..1000] of longint;
a,b,t:array[0..1000000] of longint;
function max(a,b:longint):longint;
begin 
if a>b then exit(a)
else exit(b);
end;

begin 
readln(n,m,k);
for i:=1 to n-1 do
read(d[i]);
readln;
for i:=1 to m do 
begin 
readln(t[i],a[i],b[i]);
if start[a[i]]<t[i] then start[a[i]]:=t[i];
inc(c[b[i]]);
end;
for xx:=1 to k do 
begin 
fillchar(st,sizeof(st),0);
fillchar(s,sizeof(s),0);
for i:=1 to n-1 do 
st[i+1]:=max(st[i],start[i])+d[i];
i:=1;
max1:=0;
while i<=n-1 do 
begin 
if d[i]>0 then 
begin 
j:=i;
s[j]:=c[i+1];
while st[i+1]>start[i+1] do 
begin 
inc(i);
s[j]:=s[j]+c[i+1];
end;
if s[j]>max1 then 
begin 
tt:=j; 
max1:=s[j];
end;
end;
inc(i);
end;
if max1=0 then break;
if d[tt]>0 then dec(d[tt]);
end;
ans:=0;
for i:=1 to n-1 do 
st[i+1]:=max(st[i],start[i])+d[i];
for i:=1 to m do 
ans:=ans+st[b[i]]-t[i];
writeln(ans);
end.
發佈了33 篇原創文章 · 獲贊 3 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章