本題涉及演算法:區間dp。
我們一開始要做一些初始化操作,令:
我們設狀態 \(f[l][r][i]\) 表示:
則我們可以得出狀態轉移方程如下:
\[f[l][r][0] = min(f[l+1][r][0] + (sum[l] + sum[n] - sum[r]) * (p[l+1] - p[l]), f[l+1][r][1] + (sum[l] + sum[n] - sum[r]) * (p[r] - p[l]))
\]\[f[l][r][1] = min(f[l][r-1][0] + (sum[l-1] + sum[n] - sum[r-1]) * (p[r] - p[l]),f[l][r-1][1] + (sum[l-1] + sum[n] - sum[r-1]) * (p[r] - p[r-1]))
\]實現**如下:
#include using namespace std;
const int maxn = 55;
int n, c;
long long p[maxn], // p[i]表示第i個路燈的位置
w[maxn], // w[i]表示第i個路燈的功率
sum[maxn], // sum[i]表示前i個路燈的總功率
f[maxn][maxn][2]; // f[l][r][0]表示關了[l,r]範圍內的燈並且當前在l位置的最小功率;
// f[l][r][1]表示關了[l,r]範圍內的燈並且當前在r位置的最小功率
const long long inf = (1ll<<60);
int main()
for (int i = 1; i <= n; i ++)
for (int j = i; j <= n; j ++)
f[i][j][0] = f[i][j][1] = inf;
f[c][c][0] = f[c][c][1] = 0; // 一開始在第c盞路燈不消耗電量
for (int len = 2; len <= n; len ++)
}cout << min(f[1][n][0], f[1][n][1]) << endl;
return 0;
}
洛谷 題解 P1220 關路燈
搜尋 inline void dfs int now,int l,int r,int cnt,int sum,int k now為當前點 l為左端點 r為右端點 cnt為當前耗電量 sum為開著的燈的總耗電 k為還有幾盞燈開著 if l 1 dfs l 1,l 1,r,cnt m now m l 1...
洛谷P1220 關路燈(區間dp)
某一村莊在一條路線上安裝了n盞路燈,每盞燈的功率有大有小 即同一段時間內消耗的電量有多有少 老張就住在這條路中間某一路燈旁,他有一項工作就是每天早上天亮時一盞一盞地關掉這些路燈。為了給村里節省電費,老張記錄下了每盞路燈的位置和功率,他每次關燈時也都是盡快地去關,但是老張不知道怎樣去關燈才能夠最節省電...
洛谷 P1220 關路燈 區間DP
某一村莊在一條路線上安裝了 n 盞路燈,每盞燈的功率有大有小 即同一段時間內消耗的電量有多有少 老張就住在這條路中間某一路燈旁,他有一項工作就是每天早上天亮時一盞一盞地關掉這些路燈。為了給村里節省電費,老張記錄下了每盞路燈的位置和功率,他每次關燈時也都是盡快地去關,但是老張不知道怎樣去關燈才能夠最節...