迷之阶梯

问题描述:
在经过地球防卫小队的数学家连续多日的工作之后,外星人发的密码终于得以破解。它告诉我们在地球某一处的古老遗迹中,存在有对抗这次灾难的秘密道具。防卫小队立刻派出了一个直升机小分队,迅速感到了这处遗迹。要进入遗迹,需要通过一段迷之阶梯。登上阶梯必须要按照它要求的方法,否则就无法登上阶梯。它要求的方法有以下三个限制:1. 如果下一步阶梯的高度只比当前阶梯高 1,则可以直接登上。2. 除了第一步阶梯外,都可以从当前阶梯退到前一步阶梯。3. 当你连续退下 k 后,你可以一次跳上不超过当前阶梯高度 2^k 的阶梯。比如说你现在位于第 j 步阶梯,并且是从第 j + k 步阶梯退下来的。那么你可以跳到高度不超过当前阶梯高度 + 2^k 的任何一步阶梯。跳跃这一次只算一次移动。开始时你在第 1 步阶梯。由于时间紧迫,我们需要你预先计算出登上迷之阶梯的最少动次数。输入格式:
第 1 行:一个整数 N,表示阶梯步数;第 2 行:N 个整数(每两个之间有 1 个空格),依次为每层阶梯的高度,保证递增输出格式:
输出一行一个整数,如果能登上阶梯,输出最小步数,否则输出-1。输入样例:
50 1 2 3 6输出样例:
7样例解释:
连续凳 3 步,再后退 3 步,然后直接跳上去。数据限制:
对于 50%的数据:1 <= N <= 20;对于 100%的数据:1 <= N <= 200;每步阶梯高度不超过 2^31-1。

程序:

var
n,k,i,j,w:longint;
f,a,m:array[0..300]of longint;

function min(x,y:longint):longint;
begin
    if x>y then exit(y) else exit(x);
end;


begin
    readln(n);
    for i:=1 to n do
    read(a[i]);
    m[0]:=1;
    for i:=1 to 31 do
    m[i]:=m[i-1]*2;
    for i:=1 to n do
    f[i]:=3000000;
    f[1]:=0;
    for i:=2 to n do
    begin
        if a[i-1]+1=a[i] then f[i]:=f[i-1]+1;
        for j:=1 to i-1 do
        begin
            w:=a[i]-a[j];
            for k:=0 to 31 do
            if m[k]>=w then break;
            if j+k<=i-1 then f[i]:=min(f[i],f[j+k]+k+1);
        end;
    end;
    if f[n]<3000000 then write(f[n]) else write(-1);
end.
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值