8.8 迷之阶梯 2530

题目

登上阶梯必须要按照它要求的方法,否则就无法登上阶梯。它要求的方法有以下三个限制:
1. 如果下一步阶梯的高度只比当前阶梯高1,则可以直接登上。
2. 除了第一步阶梯外,都可以从当前阶梯退到前一步阶梯。
3. 当你连续退下k后,你可以一次跳上不超过当前阶梯高度2^k的阶梯。比如说你现在位于第j步阶梯,并且是从第j + k步阶梯退下来的。那么你可以跳到高度不超过当前阶梯高度 + 2^k的任何一步阶梯。跳跃这一次只算一次移动。
开始时你在第1步阶梯。由于时间紧迫,我们需要你预先计算出登上迷之阶梯的最少移动次数。

题解

可以用动态规划
有两种情况:
1.这一步阶梯只比上一步阶梯高1,f[i]=f[i-1]+1
2.从第j(1<=j<=i-1)级阶梯退后k(1<=k<=j-1)级阶梯然后跳上这一步阶梯,f[i]=f[j]+1+(j-k)

O(n3)

也可以用搜索+记忆化,注意剪枝

代码

var
  w:array[1..200]of longint;
  m:array[0..200]of int64;
  n,i,j,k:longint;
  f:array[0..200]of longint;
begin
  assign(input,'ladder.in');
  assign(output,'ladder.out');
  reset(input);rewrite(output);
  readln(n);
  fillchar(f,sizeof(f),$7f);
  f[1]:=0;
  for i:=1 to n do
    read(w[i]);
  m[0]:=1;
  for i:=1 to 31 do
    m[i]:=m[i-1]*2;
  for i:=32 to n do
    m[i]:=m[i-1];
  for i:=2 to n do
    begin
      if (w[i]-w[i-1]=1)and(f[i-1]+1<f[i]) then f[i]:=f[i-1]+1;
      for j:=1 to i-1 do
        for k:=1 to j-1 do
          if (w[i]-w[k]<=m[j-k])and(f[j]+1+j-k<f[i]) then f[i]:=f[j]+1+j-k;
    end;
  if f[n]<>f[0] then writeln(f[n]) else writeln('-1');
  close(input);close(output);
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值