洛谷P1220 關路燈【區間dp】

題目https://www.luogu.org/problemnew/show/P1220ios

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

關燈不須要時間,走的速度是1單位/秒。問把全部的燈關掉,最少功率是多少。code

思路:看上去是區間dp還挺清楚的。由於關燈不須要時間,既然路過了就順便關了吧。因此確定是中間某一段的燈都被關了,兩端各有一段亮着。blog

因此咱們能夠用$dp[i][j]$表示i~j號燈都被關了。可是最後關的是$i$仍是$j$仍是有差異的,因此還須要一維來標記。get

由於須要區間和,因此再用$sum$維護區間前綴和string

最後獲得狀態轉移方程it

$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]))$io

$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]))$class

要注意兩個狀況燈的功率是不一樣的。stream

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

中間更新的話其實就是枚舉關了的燈的數量,而後枚舉起點就能夠了。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<map>
 4 #include<set>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<cmath> 
 9 #include<stack>
10 #include<queue>
11 #include<iostream>
12 
13 #define inf 0x7fffffff
14 using namespace std;
15 typedef long long LL;
16 typedef pair<int, int> pr;
17 
18 int n;
19 const int maxn = 55;
20 int c;
21 int light[maxn], sum[maxn], pos[maxn];
22 int dp[maxn][maxn][2];
23 
24 int main()
25 {
26     memset(dp, 0x3f, sizeof(dp));
27     scanf("%d%d", &n, &c);
28     for(int i = 1; i <= n; i++){
29         scanf("%d%d", &pos[i], &light[i]);
30         sum[i] = sum[i - 1] + light[i];
31     }
32     dp[c][c][0] = dp[c][c][1] = 0;
33     for(int num = 2; num <= n; num++){
34         for(int l = 1; l + num - 1 <= n; l++){
35             int r = l + num - 1;
36             int x = sum[l] + sum[n] - sum[r], y = sum[l - 1] + sum[n] - sum[r - 1];
37             dp[l][r][0] = min(dp[l][r][0], dp[l + 1][r][0] + (pos[l + 1] - pos[l]) * x);
38             dp[l][r][0] = min(dp[l][r][0], dp[l + 1][r][1] + (pos[r] - pos[l]) * x);
39             dp[l][r][1] = min(dp[l][r][1], dp[l][r - 1][1] + (pos[r] - pos[r - 1]) * y);
40             dp[l][r][1] = min(dp[l][r][1], dp[l][r - 1][0] + (pos[r] - pos[l]) * y);
41         }
42     }
43     
44     printf("%d\n", min(dp[1][n][0], dp[1][n][1]));
45     
46 }
相關文章
相關標籤/搜索