• Codeforces-1013E:Hills【dp】


    题意

    • 输入一串数字代表一串山坡的高度,如果当前山的高度比它两边的都要高,我们可以在上面盖一栋房子。可以用挖掘机挖山坡使其高度降低,一小时可以向下挖掉高度1(可以减到负数)。现在要分别找到想建i=1~n/2个房子,对每一个i输出需要挖掘的时间(n:5e3)

    挺恶心的一道线性dp,这个用不着区间dp,因为当前状态完全可以从前面转移

    对于第 i 个山坡,我们可以选择建或不建。

    如果建,那么第 i - 1个山坡一定不能建,我们考虑一下建房子的代价。

      1.如果 i 比 i-1 高,代价显然是0

      2.如果 i 比 i-1 低或一样高,代价是 h[i-1]-h[i]+1

      我们可以用一种简洁的方式表示代价 :max(h[i-1]-h[i]+1, 0) 

    如果不建,那么第 i-1 个山坡可以选择建或不建

      代价的讨论同上

    我们用 dp[i][j][k]表示前 i 个山坡建 j 个房子,k 表示当前山坡建或不建,1为建,0为不建

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    using namespace std;
    const int maxn = 5005;
    int h[maxn], dp[maxn][maxn][2];
    int max(int x,int y,int z){return max(z,max(x,y));}//我们一会要在三个数中取最大
    int main(){
        int n; scanf("%d", &n);
        for(int i=1; i<=n; i++) scanf("%d", &h[i]);//读入山坡高
        memset(dp, 0x3f, sizeof(dp));//记得初始化dp
        dp[1][1][1] = dp[1][0][0] = 0;
        dp[2][1][1] = max(h[1]-h[2]+1, 0);
        dp[2][1][0] = max(h[2]-h[1]+1, 0);
        dp[2][0][0] = 0;
        //对于1 2我们可以直接得出
        for(int i=3; i<=n; i++){
            for(int j=0; j<i; j++){//枚举第i个山坡前建的房子数
                dp[i][j+1][1] = min(min(dp[i][j+1][1], dp[i-2][j][1]+max(h[i-1]-h[i]+1, h[i-1]-h[i-2]+1, 0)), dp[i-2][j][0]+max(h[i-1]-h[i]+1, 0));//我知道我写的很恶心
                //第 i 个山坡建房子,房子总数+1,第i-1个山坡已经确定不能建房子,我们讨论i-2
                //dp[i-2][j][1]+max(h[i-1]-h[i]+1, h[i-1]-h[i-2]+1, 0) 第i-2个山坡建房子,对于代价,我们需要让i-1同时比i-2和i低
                //dp[i-2][j][0]+max(h[i-1]-h[i]+1, 0) 第i-2个山坡不建房子,只要让i-1比i低就好了
    
                dp[i][j][0] = min(min(dp[i][j][0], dp[i-1][j][0]), dp[i-1][j][1]+max(h[i-2]-h[i-1]+1, h[i]-h[i-1]+1, 0));
                //第 i 个山坡不建房子,房子总数为 j,第i-1山坡可以建或不建
            }
        }
        for(int i=1; i<=(n+1)/2; i++) printf("%d ", min(dp[n][i][0], dp[n][i][1]));
        return 0;
    }
  • 相关阅读:
    springboot 基础
    spring 基础
    spring MVC 基础
    windows shell
    oracle 创建用户和视图并授权
    maven 安装本地依赖
    JAVA ssl 证书
    mybatis 递归
    MyBatis基础
    当年的毕设-cpf (一个简易的协议 fuzzer)
  • 原文地址:https://www.cnblogs.com/hzoi-poozhai/p/12686806.html
Copyright © 2020-2023  润新知