sb貪心......暴露了我**能力巨弱的本質。
題面解:首先我們應該想到dp(但是我想到了貪心......)
然後分析題目本質,每個點有個限制,最早開走時間不得早於最晚上車時間。
然後我們就可以把每個人看做都在那個時間上車。
然後我們發現,對乙個地方使用加速,會影響它後面一段區間。
然後就有個暴力·雛形是列舉在某個點用加速,看它能夠減少的時間,取最大的那個用。
然後看一眼資料範圍,大概是n²,可以過,只要你每次找到收益最大的點是o(n)即可。
然後發現好難寫,細節巨多無比......一直覺得這個演算法是錯的,因為只有乙個想法,根本無法轉成**實現。
然後肝了好久,受不了了,去看題解,發現我tm想的是正解,只是不會實現......
**實現:
固定陣列:limit,up,down,sum,分別表示最晚上車時間,上車人數,下車人數,down的字首和。
變化陣列:dis,to,to_lar,now,influ,分別表示所用時間(d),最遠能影響到的位置,這條影響鏈上最多能承受減去的時間,抵達這裡的時間,這裡修改會影響的人數。
大部分可變陣列都倒序求出,now是正序求出。
然後試一下某hack資料:
4 5 13 0 2
0 1 2
0 1 4
0 1 4
0 1 4
0 1 4 ans = 18
1ac**#define wwx ak_ioi
23 #include 4 #include 5
6const
int n = 1010, inf = 0x7f7f7f7f, m = 10010;7
8struct
custom a[m];
1112
intn, m, k, dis[n], limit[n], to[n], now[n], up[n], down[n], sum[n], influ[n], to_lar[n];
1314
intmain()
19for(int i = 1; i <= m; i++)
25 sum[1] = down[1
];26
for(int i = 2; i <= n; i++)
30//
get limit sum up down
3132
while
(k)
37int large = -1, pos = -1
;38 to[n] = n - 1
; 39 to_lar[n] =inf;
40for(int i = n - 1; i >= 1; i--)
46else
50 influ[i] = sum[to[i] + 1] -sum[i];
51//
printf("influ : %d %d \n", i, influ[i]);
52if(influ[i] > large && to_lar[i] &&dis[i]) 56}
57if(to_lar[pos] == 0
) 60 to_lar[pos] =std::min(to_lar[pos], dis[pos]);
61 dis[pos] -=std::min(to_lar[pos], k);
62 k -=std::min(to_lar[pos], k);
63//
printf("pos = %d to = %d lar = %d \n", pos, to[pos], to_lar[pos]);64}
6566 now[1] = 0;67
for(int i = 2; i <= n; i++)
7071
int ans = 0;72
for(int i = 1; i <= m; i++)
7576 printf("%d"
, ans);
77return0;
78 }
洛谷P1315 觀光公交
題目 模擬 貪心 一開始看到10 5的資料,以為要klogn就敲了個線段樹上去 結果沒考慮後效性,只過了3個點 正解 一開始先處理出每一站的到站時間是對的,而隨著修改到站時間的改變不一定滿足字首關係 假設在某一站有人很晚才出發,那不管先前改變了多少後面的到站時間都是不變的 綜上 還需要維護修改一段距...
洛谷P1315 觀光公交
題目 如果沒有氮氣加速器,則該題為乙個模擬題。但是本題存在氮氣加速器,所以我們需要考慮貪心策略。題目要求我們使所有人等待的時間最短,因此我們需要算出每段路徑 路徑即為車站之間的 d 對時間的貢獻多少,取其中最多的減去就好了。首先我們需要求出每個車站最遠向右影響到什麼地方,然後算出這段地方的影響總人數...
洛谷P1315 觀光公交
風景迷人的小城y 市,擁有n 個美麗的景點。由於慕名而來的遊客越來越多,y 市特意安排了一輛觀光公交車,為遊客提供更便捷的交通服務。觀光公交車在第 0 分鐘出現在 1號景點,隨後依次前往 2 3 4 n 號景點。從第 i 號景點開到第 i 1 號景點需要 di 分鐘。任意時刻,公交車只能往前開,或在...