• 【洛谷 1929】迷之阶梯


    题目描述

    在经过地球防卫小队的数学家连续多日的工作后,外星人发的密码终于得以破解。它 告诉我们在地球某一处的古老遗迹中,存在有对抗这次灾难的秘密武器。防卫小队立即赶 到这处遗迹。要进入遗迹,需要通过一段迷之阶梯。登上阶梯必须要按照它要求的方法, 否则就无法登上阶梯。它要求的方法有以下三个限制:

    1. 如果下一步阶梯的高度只比当前阶梯高 1,则可以直接登上。

    2. 除了第一步阶梯外,都可以从当前阶梯退到前一步阶梯。

    3. 当你连续退下 k 后,你可以一次跳上不超过当前阶梯高度 2^{k}2k的阶梯。比如说你现 在位于第 j 步阶梯,并且是从第 j+k 步阶梯退下来的,那么你可以跳到高度不超过当前阶 梯高度+2^{k}2k的任何一步阶梯。跳跃这一次只算一次移动。

    开始时我们在第一步阶梯,由于时间紧迫,我们需要用最少的移动次数登上迷之阶梯。 请你计算出最少的移动步数。

    输入格式

    第一行:一个整数 N,表示阶梯步数。

    第二行:N 个整数,依次为每层阶梯的高度,保证递增。

    输出格式

    第一行:一个整数,如果能登上阶梯,输出最小步数,否则输出-1。

    输入输出样例

    输入 #1
    5
    0  1  2  3  6 
    
    输出 #1
    7

    说明/提示

    【样例解释】

    连续登 3 步,再后退 3 步,然后直接跳上去。

    【数据范围】

    对于 50%的数据:1≤N≤20。

    对于 100%的数据:1≤N≤200。

    对于 100%的数据:每步阶梯高度不超过 2^31-1

    题解:线性DP(当年我用dfs没过)

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    typedef long long ll;
    using namespace std;
    const int oo=0x3f3f3f3f;
    const int N=222;
    int n,a[N],f[N];
    int main(){
        freopen("1929.in","r",stdin);
        freopen("1929.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        memset(f,0x3f,sizeof(f));
        f[1]=0;
        for(int i=2;i<=n;i++){
            if(a[i]<=a[i-1]+1)//当前位 
               f[i]=f[i-1]+1;
            for(int j=i-1;j>=1;j--)//上一位 
                for(int k=j-1;k>=1;k--)//后退几步 
                    if( (1<<(j-k)) +a[k]>=a[i]) 
                       f[i]=min(f[i],f[j]+j-k+1);
        }
        printf("%d
    ",f[n]>=oo?-1:f[n]);
        return 0;
    }
  • 相关阅读:
    vim发现交换文件
    Linux vim 一般模式(底线模式) 命令行模式 插入模式 记录2:
    linux的停止命令
    Linux centos7 常用命令 记录1:
    linux操作系统的关机命令
    linux解密shadow_Linux密码文件passwd和shadow分析
    mysql中root用户被忽略?
    Linux笔记01
    重装系统后恢复MySQL服务,Can't create test file C:ProgramDataMySQLMySQL
    重装JDK后,输入java -version报错:could not open " xxxxjvm.cf "
  • 原文地址:https://www.cnblogs.com/wuhu-JJJ/p/11777813.html
Copyright © 2020-2023  润新知