• 洛谷P1220 关路灯【区间dp】


    题目https://www.luogu.org/problemnew/show/P1220

    题意:给定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 #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
    ", min(dp[1][n][0], dp[1][n][1]));
    45     
    46 }
  • 相关阅读:
    角色转变
    参加Google™ Code Jam 中国编程挑战赛(1)
    开始学习研究Infragistics NetAdvantage For ASP.NET
    建立资料库
    参加Google™ Code Jam 中国编程挑战赛(2)
    极度郁闷,上网时间被限定!
    在Win7下Visual Studio如何使用IIS进行调试
    jQuery 第二课:操作包装集元素
    将DataTable导出到Excel
    CSS选择符
  • 原文地址:https://www.cnblogs.com/wyboooo/p/11079806.html
Copyright © 2020-2023  润新知