這是乙個貪心,說實話開始做的時候......完全沒看出來qaq。。
首先對於每個點當然是能走就走,
不能走就等待,這是無法控制的。
所以只考慮氮氣加速器加在**可以使時間總和盡量少。
如果選擇加速,可能會使後面等待的時間更長,或者更短,對後面都會有影響。
但是沿著一條邊加速會影響後面的所有邊麼?
這可不一定
來來來,我們分類討論一下:
即每次用加速器都會對後面的人有影響,
用 $ sum_i $ 記錄到i的人數,字首和處理, $ g_i $ 代表每個點所能影響到的最遠點,
那麼 $ sum_ - sum_i $ 即是能影響到的人數
這樣就很容易想到選擇影響盡量大的點減掉(在這裡貪心)。
/*last[i] : 最後乙個人到達i站點的時間。
sum[i] : 到i站點的總人數。
enter[i] : 公交車到i站點的最少時間。
g[i] : 每個站點所能影響到的最遠站點,即要求的影響。*/
#include#include#include#include#define n 30001
using namespace std;
int n,m,k;
int dis[n],last[n],g[n],enter[n];
int ans,sum[n],maxx = -1;
struct node a[n];
inline void bus(int x)
for(int i = 1 ; i < n ; ++ i)
}ans -= maxx;//更新ans
dis[tar] --;//減掉dis
for(int i = 2 ; i <= n ; ++ i)
enter[i] = max(enter[i - 1],last[i - 1]) + dis[i - 1];//重新更新enter
}return;
}int main()
enter[1] = last[1];
for(int i = 1 ; i <= n ; ++ i)
sum[i] += sum[i - 1];//到i站點的總人數 字首和處理
for(int i = 2 ; i <= n ; ++ i)
enter[i] = max(enter[i - 1],last[i - 1]) + dis[i - 1];//公車到i站點的最少時間 和最後到的時間取max
for(int i = 1 ; i <= m ; ++ i)
ans += enter[a[i].end] - a[i].time;//處理出不加加速器的answer,後面就可以直接減啦~
bus(k);
printf("%d \n",ans);
return 0;
}
真的是考驗智商qaq... NOIP2011 觀光公交
題目 分析 設last i 表示來到第i個景點的乘客最晚的時間,time i 表示車到達第i個景點的最小時間。因為每個乘客到達的時間已經固定,所以要使總時間最小,就是使 time down i 最小,其中down i 代表每位乘客的目的地。先考慮不用加速器的情況。可以直接遞推求出答案,time i ...
NOIP2011 觀光公交
傳送門 luogu 有點麻煩,幸好 o n 2 能過。貪心地想一想,我們如果要用加速器,肯定是要選擇車上人數最多的時段加速。但是我們就會面臨這樣的情況 那麼我們就分類討論一下,預處理一些東西 每個站的下車人數,需要更新的車到站時間,每個站的最後乙個下車人數。然後隨便搞一下就好了。include in...
noip2011 公交觀光
風景迷人的小城y市,擁有n個美麗的景點。由於慕名而來的遊客越來越多,y市特意安排了一輛觀光公交車,為遊客提供更便捷的交通服務。觀光公交車在第0分鐘出現在1號景點,隨後依次前往2 3 4 n號景點。從第i號景點開到第i 1號景點需要di分鐘。任意時刻,公交車只能往前開,或在景點處等待。設共有m個遊客,...