递归问题(也许是递推) 爬楼&下山

第一次写博客,简单一点,以代码为主,毕竟刚开始接触计算机,原理得慢慢来。

分享两道题吧,感觉类型差不多,但思路略有不同,我的代码感觉不是很完善。好像也可以用动态规划,有空我再改进一下。也欢迎大家一起交流,学习。

第一道,下楼问题。

从楼上走到楼下共有h个台阶,每一步有3种走法:走一个台阶;走两个台阶;走三个台阶。规定只能往下走,不能往上走。

调皮的小明在n个台阶上撒了水,为了防止滑倒,不能踏上这n个台阶,问从楼上到楼下可走出多少种方案?

输入描述

第一行两个数字h, n,分别表示总台阶数和不能走的台阶数  (1 <= n < h <= 15)

接下来n行,每行一个整数a_i,表示第a_i级台阶被撒了水不能走

输出描述

一个整数,表示从楼上到楼下的方案数。

思路:

首先,把该接收的数据,读进来。(由于之前用vc++,支持的c++版本不太行,不能用变量定义数组元素个数。所以这里偷了个懒,也没动态开辟数组,直接搞了个最大值)

接着,把不能踩的台阶设置成1,其余是0。

然后,进入函数step,开始递归。 

 递归首先确定停止条件,这里就是最后分别剩1、2、3格的情况(这里有很多重复所以感觉可以用动态规划)。不停止的话,就按照三种步频往下走。

最后,输出。

#include<iostream>
using namespace std;
 int count=0;

int main(){
int h,n,a[15],x[15]={0};
x[0]=1;
  void step(int,int*);
  cin>>h>>n;
  for(int e=0;e<n;e++)
    cin>>a[e];
   for(int j=0;j<n;j++)
  for(int i=0;i<=h;i++)
   
      if(a[j]==i)
        x[i]=1;
 
    step(h,x);
  cout<<count<<endl;
  return 0;
  
}

void step(int h,int *x){

if((h-1)==0)
{++count;return;}

if((h-2)==0)
{if(x[1]==0) count=count+2;
else count++;return;}

if((h-3)==0)
{if(x[1]==0&&x[2]==0)count=count+4;
else if(x[1]==0||x[2]==0)count=count+2;
else count++;return;

}

for(int e=1;e<=3;e++)
     if(x[h-e]==0&&(h-e)>0)
         step(h-e,x);

  

}

 第二道,猴子跳台阶

一个顽猴在一座有N级台阶的小山上爬山跳跃,猴子上山一步可跳x级或跳y级,试求猴子上山到N级台阶有多少种不同的爬法?猴子从山脚开始跳,可认为是第0阶。

输入描述

三个正整数N,X,Y,用空格隔开。 (x <= y <= N <= 100)

输出描述

猴子上山到第N级台阶有多少种不同的爬法,如果不能到达则输出“sorry”。

思路:

与上一题相反,我们从下往上走,但思路是一样的。相同的地方看代码就好。

差别在于步频是用户输入的。

我一开始错在没有判断x是否等于y,会出问题。

那么,在递归中,剩余台阶数等于x时,可以直接count++,然后结束,但由于y比x大,所以虽然等于y,但还得算一下x的可能性。这个递归是在不断判断中进行的,所以到处都是climb函数,如果有更好的方法,欢迎批评。

#include<iostream>
using namespace std;
int count=0;

int main(){
int N,X,Y;
void climb(int n,int x,int y);
  cin>>N>>X>>Y;
    if(X!=Y)climb(N,X,Y);
  else if(N%X==0) count++;
  
  if(count==0)
    cout<<"sorry"<<endl;
  else cout<<count<<endl;
  return 0;
}

void climb(int n,int x,int y){

  if((n-x)==0)
{count++;return;}
  if((n-y)==0)
  {count++;climb(n-x,x,y);return;}
  
  
  if((n-y)>0)
  {climb(n-y,x,y);
    climb(n-x,x,y);
  }
  else if((n-x)>0) climb(n-x,x,y);
    else return;
}

欢迎抬杠,我很需要,菜菜捞捞!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值