zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    SCAU 9504 面试
    SCAU 9503 懒人选座位
    SCAU 8628 相亲
    SCAU 10691 ACM 光环
    SCAU 8626 原子量计数
    SCAU 10674 等差对
    HDU ACM 1048 The Hardest Problem Ever (水题)
    SCAU 9502 ARDF
    SCAU 10686 DeathGod不知道的事情
    SCAU 8629 热身游戏(高精度)
  • 原文地址:https://www.cnblogs.com/hzoi-poozhai/p/12686806.html
Copyright © 2011-2022 走看看