问题描述
如果我每一步迈上 1 个或两个台阶,先迈左脚,然后左右交换,最后一步迈右脚,也就是一共要走偶数步,那么,上完 39 级台阶,有多少种不同的算法?
思路一(递归)
不管走的是左脚还是右脚,只要走的步数是偶数即可,递归的思想
39,0
38,1 37,1
37,2 36,2 36,2 35,2
… … … … … … … …
输出:Total=51167078 请等待几秒
- 从顶部算起
#include<iostream>
using namespace std;
int total=0;//计数
int sum(int num,int step)
{
if(num<0)
return 0;
if(num==0&&step%2==0)//不管走的是左脚还是右脚,只要走的步数是偶数即可。
{
total++;
return 0;
}
sum(num-1,step+1);
sum(num-2,step+1);
}
int main()
{
int n;
cin>>n;
sum(n,0);//从顶部算起
cout<<total<<endl;
return 0;
}
- 从底部算起
#include<iostream>
using namespace std;
int total=0;
int sum(int num,int step)
{
if(num>39)
return 0;
if(num==39&&step%2==0)
{
total++;
return 0;
}
sum(num+1,step+1);
sum(num+2,step+1);
}
int main()
{
sum(0,0);//从底部算起
cout<<total<<endl;
return 0;
}
思路二(非递归)
#include<iostream>
using namespace std;
long fact(int m,int n)
{
int i;
double a,b,c;//因为阶乘数m,n稍大,阶乘结果变大。
a=b=c=1;
for(i=m+n;i>0;i--)
a*=i;
for(i=m;i>0;i--)
b*=i;
for(i=n;i>0;i--)
c*=i;
return a/(b*c);
}
int main()
{
int i,j;
long sum=0;
for(i=1;i<=37;i++)
for(j=1;j<=19;j++)
{
if((i+j)%2==0&&(i+2*j)==39)//满足两只脚走的总的歩数为偶数且走的阶梯数总和为39
{
sum+=fact(i,j);//求总的组合数
cout<<i<<j<<endl;//输出两只脚的种类数
}
}
cout<<sum<<endl;
return 0;
}
一般采用递归的思想,非递归的想法需要很强的数学功底,不然难以解决。
递归是解决问题的一个捷径,就是算法复杂度较高。