jzxx2852觀光公交

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

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

樣例
輸入
3 3 2
1 4
0 1 3
1 1 2
5 2 3
輸出
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≤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 bus;
const maxn=10001;
var
    down,ans,late,t,a,b,p,d:array[0..maxn]of longint;
    n,m,k,i,j,l,r,daan:longint;
function max(x,y:longint):longint;
begin
      if x>y then exit(x) else exit(y);
end;
procedure reduce(l,r:longint);
var
    i,j,s:longint;
begin
      fillchar(p,sizeof(p),0);
      for i:=l to r do
      ans[i+1]:=max(ans[i],late[i])+d[i];
      i:=1;s:=0;
      while i<n do
      begin
           if d[i]>0 then
           begin
                j:=i;
                p[j]:=down[i+1];
                while ans[i+1]>late[i+1] do
                begin
                      inc(i);
                      p[j]:=p[j]+down[i+1];
                end;
                if p[j]>p[s] then s:=j;
           end;
           inc(i);
      end;
      if p[s]=0 then begin k:=0; exit; end;
      dec(d[s]);dec(k);
      l:=s;r:=n-1;
end;
begin
      read(n,m,k);
      for i:=1 to n-1 do
      read(d[i]);
      for i:=1 to m do
      begin
            readln(t[i],a[i],b[i]);
            inc(down[b[i]]);
            late[a[i]]:=max(late[a[i]],t[i]);
      end;
      l:=1;r:=n-1;
      while k>0 do
      reduce(l,r);
      for i:=1 to n-1 do
      ans[i+1]:=max(ans[i],late[i])+d[i];
      for i:=1 to m do
      inc(daan,ans[b[i]]-t[i]);
      write(daan);
end.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章