標籤:style os 問題 時間 size on sp 網路
題目大意:
一條數軸上有 n 個 MM 在哭,需要tcboy去安慰,tcboy 一開始站在第k個MM身邊,每個MM 哭都會減掉tcboy的RP。
確定安慰MM的順序使得RP扣得最少。求 min(Rp_cost); (安慰不要時間。。。)
其實就是經典的關燈問題: 一條數軸上有很多燈,需要全部關掉,每盞燈的每分鐘的耗電量不一樣,確定關燈順序 使得耗電最少。(關燈不要時間。)
解題過程:
1.首先想到 如果人經過了一盞燈,那麼必定把它關掉,否則答案不會更優。
2.其次想到 關掉一個區間的最後一盞燈後 人的位置 必定是 在在各個區間的最左端或者最右端。因為如果是站在中間的位置x,那麼區間的兩頭肯定也走過了,既然兩頭都走過了,再走兩頭之前 x必定也走過了,根據1,這樣肯定不會最優。
3.定義F[i][j][0] 為關掉區間[i,j]的所有燈,且人站在 i 的時候 的最小花費。F[i][j][1] 為關掉區間[i,j]的所有燈,且人站在 j的時候 的最小花費。 time為相應所需要的時間;
先看F[i][j][0] (F[i][j][1]的方法類似 ),必定是由 F[i+1][j][0] 或者F[i+1][j][1]轉移過來。
那麼F[i][j][0]=
min{F[i+1][j][0]+cost[i]*(time[i+1][j][0]+dist[i][i+1]) , F[i+1][j][1]+cost[i]*(time[i+1][j][1]+dist[i][j])};
但是如何 求出 time數組呢? 用類似F的方法轉移? 一開始這樣寫 只過了 4個點,想了好久才明白 這裡陷入了一個誤區,
如果time用類似F的方法轉移,那麼time[i][j][0] 得到的 其實 是 關掉區間[i,j]的所有燈,且人站在 i 的時候 的最短時間,是和F[i][j][0] 不對應的, 因為時間最短不代表 cost 最小。然後我就換了一種方法。
4. 現在想想 這種方法修改一下其實應該也可以做(我還沒寫過):time[i][j][0]應該由F[i][j][0]決定,如果F[i][j][0]是從F[i+1][j][0]轉移過來的,那麼time[i][j][0]也從time[i+1][j][0]轉移過來,否則從time[i+1][j][1]轉移過來。
5.網路上的標準解法(我後來改成這樣了):
定義F[i][j][0] 為關掉區間[i,j]的所有燈,且人站在 i 的時候,[1,n]的燈最少已經花費了多少。
之前的做法 在求區間[i,j]的時候 是不考慮[1,i-1]和 [i+1,n]的燈的花費的,現在要算。
sum[i,j]表示 區間[i,j]的燈的單位花費和。實現的時候可以用首碼和最佳化。
那麼方程就變成:
F[i][j][0]=
min{F[i+1][j][0]+dist[i][i+1]*(sum[1,i]+sum[j+1,n]) , F[i+1][j][1]+dist[i][j]*(sum[1,i]+sum[j+1,n]) };
F[i][j][1]同理;
ans=min{F[1][n][0],F[1][n][1]};