洛谷P1220 關路燈 區間dp

2022-06-26 03:15:11 字數 1409 閱讀 2572

題目

題意:給定n盞燈的位置和功率,初始時站在第c盞處。

關燈不需要時間,走的速度是1單位/秒。問把所有的燈關掉,最少功率是多少。

思路:看上去是區間dp還挺清楚的。因為關燈不需要時間,既然路過了就順便關了吧。所以肯定是中間某一段的燈都被關了,兩端各有一段亮著。

所以我們可以用$dp[i][j]$表示i~j號燈都被關了。但是最後關的是$i$還是$j$還是有差別的,所以還需要一維來標記。

因為需要區間和,所以再用$sum$維護區間字首和

最後得到狀態轉移方程

$dp[i][j][0] = min(dp[i+1][j][0] + (pos[i+1] - pos[i]) * (sum[i] + sum[n] - sum[j]), dp[i+1][j][1] + (pos[j] - pos[i]) * (sum[i] + sum[n] - sum[j]))$

$dp[i][j][1] = min(dp[i][j-1][1] + (pos[j] - pos[j - 1]) * (sum[n] - sum[j - 1] + sum[i - 1]), dp[i][j-1][0] + (pos[j] - pos[i]) * (sum[n] - sum[j - 1] + sum[i - 1]))$

要注意兩個情況燈的功率是不同的。

初始情況和結束情況都比較好判斷。

中間更新的話其實就是列舉關了的燈的數量,然後列舉起點就可以了。

1 #include2 #include3 #include4 #include

5 #include6 #include7 #include8 #include9 #include10 #include11 #include12

13#define inf 0x7fffffff

14using

namespace

std;

15 typedef long

long

ll;16 typedef pairpr;

1718

intn;

19const

int maxn = 55;20

intc;

21int

light[maxn], sum[maxn], pos[maxn];

22int dp[maxn][maxn][2

];23

24int

main()

2532 dp[c][c][0] = dp[c][c][1] = 0;33

for(int num = 2; num <= n; num++)42}

4344 printf("

%d\n

", min(dp[1][n][0], dp[1][n][1

]));

4546 }

洛谷P1220 關路燈(區間dp)

某一村莊在一條路線上安裝了n盞路燈,每盞燈的功率有大有小 即同一段時間內消耗的電量有多有少 老張就住在這條路中間某一路燈旁,他有一項工作就是每天早上天亮時一盞一盞地關掉這些路燈。為了給村里節省電費,老張記錄下了每盞路燈的位置和功率,他每次關燈時也都是盡快地去關,但是老張不知道怎樣去關燈才能夠最節省電...

洛谷 P1220 關路燈 區間DP

某一村莊在一條路線上安裝了 n 盞路燈,每盞燈的功率有大有小 即同一段時間內消耗的電量有多有少 老張就住在這條路中間某一路燈旁,他有一項工作就是每天早上天亮時一盞一盞地關掉這些路燈。為了給村里節省電費,老張記錄下了每盞路燈的位置和功率,他每次關燈時也都是盡快地去關,但是老張不知道怎樣去關燈才能夠最節...

洛谷P1220關路燈 區間dp

某一村莊在一條路線上安裝了 n 盞路燈,每盞燈的功率有大有小 即同一段時間內消耗的電量有多有少 老張就住在這條路中間某一路燈旁,他有一項工作就是每天早上天亮時一盞一盞地關掉這些路燈。為了給村里節省電費,老張記錄下了每盞路燈的位置和功率,他每次關燈時也都是盡快地去關,但是老張不知道怎樣去關燈才能夠最節...