zoukankan      html  css  js  c++  java
  • 「区间DP」关路灯

    关路灯

    原题链接:关路灯

    题目大意

    给你一条直线,直线上有(n)个点,每个点每秒都有消耗能量,现在再给你个点(m),代表你当前的位置,现在你要去碰这些点,当你碰到这些点时,这些点就不再消耗能量,你的速度是1m/s,现在让你求碰完这些点消耗能量最少,且最少值为多少

    题目题解

    看了一下题,哎,这题还写了不能用贪心,那就dp咯,还发现每次只能碰一个点,那似乎可以用区间动规(dp_{i, j})来表示我们目前的状态,代表已经碰了 (i, j) 这个区间的点时所消耗的最小能量,用小区间去合成大区间,每次又给你你得停留在哪边,两个状态肯定不够,再设一个状态 (dp_{i, j, k}) 表示走了 (i, j) 区间后在哪边。

    因为有消耗,为了很快的计算这个消耗,我们可以用前缀和维护,然后套模板就好了?

    推导公式如下

    太长了 写了半天发现并没有空间解释 我直接写在代码里面吧

    //#define fre yes
    
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    
    const int N = 105;
    int place[N], p[N], sum[N];
    int f[N][N][2];
    
    int main() {
        static int n, m;
        scanf("%d %d", &n, &m);
        for (int i = 1; i <= n; i++) {
            scanf("%d %d", &place[i], &p[i]);
        }
        for (int i = 1; i <= n; i++) {
            sum[i] = sum[i - 1] + p[i];
        }
    
        memset(f, 1, sizeof(f));
        f[m][m][0] = f[m][m][1] = 0;
        for (int p = 1; p < n; p++) {
            for (int i = 1, j = i + p; i <= n && j <= n; i++, j++) {
                f[i][j][0] = std::min(f[i + 1][j][0] + (place[i + 1] - place[i]) * (sum[n] - sum[j] + sum[i]), f[i + 1][j][1] + (place[j] - place[i]) * (sum[n] - sum[j] + sum[i]));
                //用小区间更新大区间 
                //place[i + 1] - place[i] -> 意思是走的秒数
                //sum[n] - sum[j] + sum[i] -> 计算能量消耗
                f[i][j][1] = std::min(f[i][j - 1][1] + (place[j] - place[j - 1]) * (sum[n] - sum[j - 1] + sum[i - 1]), f[i][j - 1][0] + (place[j] - place[i]) * (sum[n] - sum[j - 1] + sum[i - 1]));
            }
        }
    
        printf("%d
    ", std::min(f[1][n][0], f[1][n][1]));
        //最后的状态不知道哪边更小 比一下
        return 0;
    }
    
  • 相关阅读:
    2016奇虎360研发工程师内推笔试编程题:找镇长
    2016奇虎360研发工程师内推笔试编程题:找到字符串第一个只出现一次的字符
    lintcode: 最长无重复字符的子串
    lintcode :同构字符串
    lintcode : 跳跃游戏
    lintcode :单词搜索
    Project Euler 110:Diophantine reciprocals II 丢番图倒数II
    Project Euler 109 :Darts 飞镖
    Project Euler 108:Diophantine reciprocals I 丢番图倒数I
    Project Euler 107:Minimal network 最小网络
  • 原文地址:https://www.cnblogs.com/Nicoppa/p/11507504.html
Copyright © 2011-2022 走看看