多少种走法?

有一类比较有趣的算法题。题目要求的是,按照一定的规则,在一个一维或二维的空间中,走到某个点,一共有多少种走法。我在这里介绍一下我遇到过的题:

1、青蛙跳台阶

一只青蛙一次只能跳一阶或两阶台阶,总共要跳n阶(n>=1),求总共有多少种跳法?

令f(n)为“跳n级台阶共有多少种跳法”。

显然,f(1)=1,f(2)=2。

那么当n>2时,我们可以对青蛙的第一步进行分类讨论,它第一步要么跳1阶,要么跳2阶。

当它第一步跳一级台阶的时候,跳n阶共有f(n-1)种跳法。

当它第一步跳两级台阶的时候,跳n阶共有f(n-2)种跳法。

两种情况加起来,得到f(n)=f(n-1)+f(n-2)。这就是我们要得到的动态规划结果,这也是个斐波那契数列。

一般来说,不建议直接在代码中写成递归实现。递归算法虽然代码很简单,但效率却非常低。

扫描二维码关注公众号,回复: 862408 查看本文章

详见https://blog.csdn.net/qq_33951180/article/details/52484080。

2、蚂蚁从原点爬到坐标x,y有多少种爬法?

一只蚂蚁位于坐标原点(0,0),它每次只能在x正方向上爬一个单位,或者往y正方向爬一个单位。请问它爬到坐标(x,y)有多少种爬法(x,y都大于0)?

解法1:动态规划

建立一个x+1行y+1列的动态规划矩阵dp。dp[i][j]表示“从原点爬到坐标i,j有多少种爬法”,i>=0,j>=0

首先将dp初始化,将它的第一行第一列都初始化为1。因为如果i,j中其中一个为0,那就只有一种爬法(直接往那个方向爬)。

对其余的dp中的元素逐行填表,dp[i][j]=dp[i-1,j]+dp[i,j-1]。跟第一题青蛙跳台阶类似,分成“第一步往x方向走”和“第二步往y方向走”两种情况。

我们以x=3和y=3为例:

初始化:

  0 1 2 3
0 1 1 1 1
1 1      
2 1      
3 1      

填入其余元素

  0 1 2 3
0 1 1 1 1
1 1 2 3 4
2 1 3 6 10
3 1 4 10 20

于是得到结果为dp[3][3]=20。

当然,这个方法可以优化空间复杂度,这里就不多说了。

解法2:直接用组合

其实有一种更加直接的思路。首先,根据题目的限定条件,蚂蚁爬到(x,y)点一定是爬了(x+y)步的!而且这x+y步中,一定有x步是往x方向走,y步是往y方向走。那问题其实就变为“从x+y步中取出x步,让这x步是往x方向走,共有多少种取法?”(又或者是“从x+y步中取出y步,让这y步是往y方向走,共有多少种取法?”)

因此,令f(x,y)为“爬到坐标(x,y)有多少种爬法”,f(x,y)=C(x+y,x)=C(x+y,y)。

3、从原点出发,一步只能向右走、向上走或向左走,每一步都只能走一个单位长度。恰好走N步且不经过已走的点共有多少种走法?

解法:动态规划。这道题的难点在于,“不经过已走的点”,这个条件应该如何处理。

用一个N*3维的动态规划矩阵,矩阵中,dp[i][0],dp[i][1],dp[i][2]分别表示,“最后一步是往上,左,右走的情况下,走i步有多少种走法”。

首先初始化dp的第一行,dp[1,0]=dp[1][1]=dp[1][2]=1。

dp[i][0]=dp[i-1][0]+dp[i-1][1]+dp[i-1][2],这个好理解,因为如果最后一步是往上走的,那走出这一步一定不会导致经过已有的点。

dp[i][1]=dp[i-1][0]+dp[i-1][1]的意思是说,如果最后一步是往左走的,那上一步不能是往右走的(如果上一步是往右走,那就回到上一步结束后的那个点了),因此dp[i][1]=dp[i-1][0]+dp[i-1][1]。

dp[i][2]=dp[i-1][0]+dp[i-1][2]同理。

最后,我们需要的结果f(N)= dp[N][0]+dp[N][1]+ dp[N][2]。

猜你喜欢

转载自blog.csdn.net/qq_26286193/article/details/80291362