楼梯

来源:互联网 发布:天猫小二和淘宝小二 编辑:程序博客网 时间:2024/04/20 23:06

题目描述

有N级楼梯,第i级楼梯的高度是H[i]。你必须通过一系列的操作来爬楼梯,每一步,你只能做如下三个选择之一:

  1、如果后一级楼梯的高度比你当前所在楼梯的高度恰好高1,那么你可以从当前楼梯爬上后一级楼梯。

  2、只要你不是在第1级楼梯,如果你愿意,你可以从当前楼梯后退到前一级楼梯。

       3、假如你最近K步都是在后退(不妨假设现在退到了第i级楼梯),那么你可以从当前的第i级楼梯走一步到达第j级楼梯,其中j > i,而且 满足H[j] – H[i] <= 2^K。其中2^K表示2的K次方。

你一开始在第1级楼梯,你至少要走多少才能到达第N级楼梯?如果无法到达第N级楼梯,输出-1。

第三题,其实可以用一个dfs直接打过,最主要还可以用dp扫过。在此我两个方法都介绍一下:

Dfs:首先,我们需要带入三个参数(t,h,s)t表示现在走到第t级楼梯,h表示走到现在一共连续退后了h步,s表示走到这一格一共走了s步。然后只需要一个出口,这个我就不说了。然后就是三种情况,一种是走一格,一种是后退,一种是“蹦”上去。那么我们只需要每个都判断一个遍就可以了。

Dp:f[i]表示走到第I格的最短路。只需要每个判断一下两种情况,一个直接走来的,一个“蹦”过来的。其中“蹦”过来的需要注意加上退后的步数。


代码:

procedure dg(t,h,sum:longint);var        i,j:longint;begin        if t=n then        begin                exit;        end;        if (a[t+1]-a[t]=1)and(sum+1<b[t+1]) then        begin                b[t+1]:=sum+1;                dg(t+1,0,sum+1);        end;        if t>1 then        begin                dg(t-1,h+1,sum+1);        end;        if (h>1) then        begin                j:=find(h);                a[n+1]:=maxlongint;                for i:=t+h to n+1 do                begin                        if a[i]-a[t]>j then break;                end;                if i=t+h then exit;                if sum+1<b[i-1] then                begin                        b[i-1]:=sum+1;                        dg(i-1,0,sum+1);                end;        end;end;


0 0