zoukankan      html  css  js  c++  java
  • 洛谷P1220 关路灯 题解 区间DP

    题目链接:https://www.luogu.com.cn/problem/P1220

    本题涉及算法:区间DP。

    我们一开始要做一些初始化操作,令:

    • \(p[i]\) 表示第i个路灯的位置;
    • \(w[i]\) 表示第i个路灯的功率;
    • \(sum[i]\) 表示前i个路灯的总功率

    我们设状态 \(f[l][r][i]\) 表示:

    • \(i=0\) 时,老张关了编号 \([l,r]\) 范围内的所有灯,并且此时老张在第 \(l\) 盏灯处(最左边)的最少消耗电量;
    • \(i=1\) 时,老张关了编号\([l,r]\) 范围内的所有灯,并且此时老张在第 \(r\) 盏灯处(最右边)的最少消耗电量。

    则我们可以得出状态转移方程如下:

    \[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 <bits/stdc++.h>
    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() {
        cin >> n >> c;
        for (int i = 1; i <= n; i ++) {
            cin >> p[i] >> w[i];
            sum[i] = sum[i-1] + w[i];
        }
        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 ++) {
            for (int l = max(1, c-len+1); l+len-1 <= n; l ++) {
                int r = l+len-1;
                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]));
            }
        }
        cout << min(f[1][n][0], f[1][n][1]) << endl;
        return 0;
    }
    
  • 相关阅读:
    IDEA修改git账号及密码的方法
    深入浅出数据库索引原理
    切勿用普通for循环遍历LinkedList
    在Jquery里格式化Date日期时间数据
    Java 根据年月日精确计算年龄
    jquery判断页面元素是否存在
    js中 '枚举' 的使用
    springMVC怎么接受前台传过来的多种类型参数?(集合、实体、单个参数)
    jquery批量绑定click事件
    springMVC怎么接收日期类型的参数?
  • 原文地址:https://www.cnblogs.com/quanjun/p/11954631.html
Copyright © 2011-2022 走看看