以下內容**z2415445508
只是為了方便自己複習而已
題目傳送門-->關路燈
關燈不需要額外的時間,經過了燈就關了。但是可能折返回去關某乙個大燈會比繼續往下走關接下來的乙個小燈更優,
那麼可以得到兩種狀態(沿著當前方向繼續往下走,改變方向回去關燈)。
我們需要得到的整個關燈過程中的最優值(最小耗能)
那麼要設計的狀態轉移方程中肯定有兩種方案(折返的,不撞牆不回頭的)
又因為如果想要關某一區間的燈的過程中耗能最小,所以可以轉換成乙個個區間來寫:
去關某一區間的燈,那麼整條街道上除了這一區間的燈會逐漸滅掉其他肯定會全亮。
那麼我們把\(f[i][j]\)記為當從i到j的燈都熄滅後剩下的燈的總功率。
再進一步:\(f[i][j][0]\)表示關掉i到j的燈後,老張站在i端點,\(f[i][j][1]\)表示關掉\([i][j]\)的燈後,老張站在右端點
(i為左端點,j為右端點)
又\(f[i][j][0]\)會由兩種方案推導而來(上面有寫。):折返回來關\(i,j\)的燈、由\(i+1\)深入,繼續關第i盞燈從而擴充套件到\((i,j)\);
所以得到狀態轉移方程:
\(f[i][j][0] = min ( f[i+1][j][0] + ( a[i+1] - a[i] ) * ( sum[i] + sum[n] - sum[j] ) , f[i+1][j][1] + ( a[j]-a[i] ) * ( sum[i]+sum[n]-sum[j]) );\)
\(f[i][j][1] = min ( f[i][j-1][0] + ( a[j] - a[i] ) * ( sum[i-1] + sum[n] - sum[j-1] ) , f[i][j-1][1] + ( a[j]-a[j-1] ) * ( sum[i-1] + sum[n] - sum[j-1] ) );\)
(列舉現在的路燈l(2-n,因為第c位的路燈已經被關了),\(i+l-1<=n\)(路只有這麼長),\(j=i+l-1\)(右端點))
因為最後不知道老張到底站在左端點最優還是站在右端點最優
所以在\(f[1][n][0]\)和\(f[1][n][1]\)中取\(min\)輸出。
**:
#include using namespace std;
int n,c;
int a[59],v[59],sumn[59];
int dp[51][51][2];
int main()
} cout
}
P1220關路燈(題解)
某一村莊在一條路線上安裝了n盞路燈,每盞燈的功率有大有小 即同一段時間內消耗的電量有多有少 老張就住在這條路中間某一路燈旁,他有一項工作就是每天早上天亮時一盞一盞地關掉這些路燈。為了給村里節省電費,老張記錄下了每盞路燈的位置和功率,他每次關燈時也都是盡快地去關,但是老張不知道怎樣去關燈才能夠最節省電...
題解 P1220 關路燈
區間dp,考慮設 dp i j t 為已經關掉了 i,j 的電燈,人在t端點處時的最小代價 可以推出方程 dp i 1 j 0 p n p j p i loc i 1 loc i dp i j 0 dp i j 1 0 p n p j 1 p i 1 loc j loc i dp i j 1 dp ...
洛谷 P1220 關路燈
某一村莊在一條路線上安裝了n盞路燈,每盞燈的功率有大有小 即同一段時間內消耗的電量有多有少 老張就住在這條路中間某一路燈旁,他有一項工作就是每天早上天亮時一盞一盞地關掉這些路燈。為了給村里節省電費,老張記錄下了每盞路燈的位置和功率,他每次關燈時也都是盡快地去關,但是老張不知道怎樣去關燈才能夠最節省電...