[讨论]上20阶楼梯,可以一次迈1,2,4步,请问有多少种上法?

百分百好牛 2012-05-24 05:37:47
加精
上20阶楼梯,可以一次迈1,2,4步,请问有多少种上法?
这样的题目,貌似有很多的。
比如:有N阶楼梯,一次可以上1层,或者2层,问一共有多少种上法。


int func1(int n)
{
if (0 == n) return 0;
if (1 == n) return 1;
if (2 == n) return 2; //一次上两层,或者一次上一层;共两种上法

return func1(n-1) + func1(n-2);
}


我也曾经看到过,如果 一次可以上1,2,3步,共有多少种上法?貌似也可以按上面的递归来做。

但是,如果一次可以上1, 2, 4层次呢?难道是一样的,可以按上面的递归做么? 总感觉到了4,就不是那么简单了。
但想不明白。列出来大家讨论一下。

欢迎畅所欲言!
...全文
7065 137 打赏 收藏 转发到动态 举报
写回复
用AI写文章
137 条回复
切换为时间正序
请发表友善的回复…
发表回复
h_w_m 2012-10-30
  • 打赏
  • 举报
回复
高数丢光了,什么通项式和对角矩阵法 我完全看不懂,只会循环和递归了 汗颜
WizardOz 2012-10-30
  • 打赏
  • 举报
回复
LZ的算法显然不对的,不能遍历所有情况。
这个问题其实是“换零钱”问题,一样一样的。
白米若雪 2012-10-28
  • 打赏
  • 举报
回复
这个通式要求浮点数幂计算,不一定能比得上矩阵法。只是做为这个问题完整讨论的补充。
白米若雪 2012-10-28
  • 打赏
  • 举报
回复
借用matlab,计算了下这个题目的近似通式:
f(n)=
(6868224515692809/72057594037927936+5188570295917323/72057594037927936*i)/((3874534210341939/18014398509481984+5886840975593053/4503599627370496*i)^(n+1))+(6868224515692809/72057594037927936-5188570295917323/72057594037927936*i)/((3874534210341939/18014398509481984-5886840975593053/4503599627370496*i)^(n+1))+1/5/((-1)^(n+1))+5488703274869591/9007199254740992/((320791565274941/562949953421312)^(n+1))

计算
f(0)=1
f(1)=2
f(2)=3
f(3)=6
f(4)=9.999999999999996,约为10

f(20)=8.204699999999981e+004,约为82047
蜡笔小新啦 2012-10-24
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 的回复:]

仅供参考C/C++ code
//问题是这样,有N个数字,数值不同,要列出用他们不同的组合相加等于1000的情况。
//比如,a[3]={200,300,400}
//则有的情况为:
//5 0 0
//3 0 1
//2 2 0
//1 0 2
//0 2 1
//等情况。
#include <stdio.h>
int a[3]={200,300,400};
int temp[3]={0,0……
[/Quote]

应该是这样的吧?36种解法。
shellJ 2012-10-02
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

Java code

int func1(int n)
{
if (1 == n) return 1;
if (2 == n) return 2;
if (3 == n) return 3;
if (4 == n) return 6;

return func1(……
[/Quote]
好思路,有才
haorengoodman 2012-09-12
  • 打赏
  • 举报
回复
public static int getResult(int step1,int step2,int step3,int sum){
int temp = 0;
int flag = 0;
for(int i=0;i<sum/step1;i++){
for(int j=0;j<sum/step2;j++){
for(int k=0;k<sum/step3;k++){
temp = step1*i + step2*j + step3*k;
if(temp == sum){
flag++;
System.out.println(i + "*1 " + j + "*2 " + k + "*4 ");
}
}
}
}
System.out.println(flag);
return flag;
}
HimeTale 2012-09-10
  • 打赏
  • 举报
回复
[Quote=引用 129 楼 的回复:]

不是有答案了吗,视而不见啊。
[/Quote]
发错帖了,无视。
HimeTale 2012-09-10
  • 打赏
  • 举报
回复
不是有答案了吗,视而不见啊。
闲谈共视 2012-08-22
  • 打赏
  • 举报
回复
//用最最笨的方法对所有的情况进行遍历:
//问题分析:可以进行数组的遍历的问题的方式进行解决:
//具体的代码如下:
#include<stdio.h>
int main()
{
int x; //全部走一个阶梯需要20个1,如果一次走一个阶梯中参杂着2、4则,1应该出现偶数次
int y; //全部走两个阶梯需要10个2
int z; //全部走四个阶梯需要5个4
int count=0; //计数器
for(x=0;x<=20;x=x+2) // 1应该出现偶数次
{
for(y=0;y<=10;y++)
{
for(z=0;z<=5;z++)
{
if(x*1+y*2+z*4==20)
{
count++;
}
else
{
continue;
}
}
}
}
printf("%d",count);
}
路口转弯 2012-08-21
  • 打赏
  • 举报
回复
好深奥的东西呀
HimeTale 2012-08-16
  • 打赏
  • 举报
回复
求通项的大致思路应该是转成对角矩阵吧。
为啥我算出来的特征方程跟10楼不一样呢
我算的是x^4-x^3+x^2+1=0
HimeTale 2012-08-16
  • 打赏
  • 举报
回复
[Quote=引用 123 楼 的回复:]

121楼的方法我过去在解决另外一个问题时用过,所以可以很快就得到比较简化的结果:
http://blog.csdn.net/mathe/article/details/2826067
[/Quote]
膜拜大牛,顺便在那边注册了一下...
mathe 2012-08-16
  • 打赏
  • 举报
回复
121楼的方法我过去在解决另外一个问题时用过,所以可以很快就得到比较简化的结果:
http://blog.csdn.net/mathe/article/details/2826067
mathe 2012-08-16
  • 打赏
  • 举报
回复
[Quote=引用 120 楼 的回复:]
另外,牛顿迭代法好像只能求实根,不能求虚根。
[/Quote]
牛顿迭代法可以求虚根,只是要求非实数的初始值
mathe 2012-08-16
  • 打赏
  • 举报
回复
设n级阶梯有a(n)种上法,容易给出初始条件a(1)=1,a(2)=2,a(3)=3,a(4)=5,
而且a(n+4)=a(n+3)+a(n+2)+a(n),为了方便起见,我们还可以利用递推式倒推出a(0)=a(4)-a(3)-a(2)=0,a(-1)=a(3)-a(2)-a(1)=0.
递推式对应的特征方程为x^4-x^3-x^2-1=(x+1)(x^3-2x^2+x-1)
我们现在看初始值为b(-1)=0,b(0)=0,b(1)=1而递推式为b(n+3)=2b(n+2)-b(n+1)+b(n)的数列
我们可以得出b(2)=2*1-0+0=a(2),由此我们可以知道b(n)=a(n)(其四项相同,而有相同四阶递推式必然相同).
也就是验证了a(n+3)=2a(n+2)-a(n+1)+a(n) (当然实际上我是数值计算通项中(-1)^n的系数发现其为0)

而对于任意初始值前k-1项为0,第k项为1的k阶递推式,计算其通项非常简单
假设对应特征多项式f(x)的k个根为r1,r2,...,rk
将前k项值代入就是要求解方程
[r1^0 r2^0 ... rk^0 ] [u1] [0]
[r1^1 r2^1 ... rk^1 ] [u2] = [0]
[ ............................ ] [..] [.]
[r1^{k-1} r2^{k-1} ... rk^{k-1}] [uk] [1]
这个可以直接计算,分母是范德蒙行列式,所以就是\prod_{i<j} (rj-ri)
而对于每个系数的分子,就是将行列式一列用右边替换,变成低一阶的范德蒙行列式,
所以得到的结果必然是uh=1/\prod{i!=h}(rh-ri)=1/f'(rh)
于是我们得出这种情况的通项可以写成
a(n)=r1^n/f'(r1)+r2^n/f'(r2)+...+rk^n/f'(rn)
而对于我们这个题,由于我们需要从a(-1)而不是a(0)开始,于是相当于平移一项,所以改成
a(n)=r1^(n+1)/f'(r1)+r2^(n+1)/f'(r2)+r3^(n+1)/f'(r3)
数值计算方程x^3-2x^2+x-1=0的三个根得到
r1=1.754877666246692760049508896,
r2=0.1225611668766536199752455518-0.7448617666197442365931704286i
r3=0.1225611668766536199752455518-0.7448617666197442365931704286i
其中|r2|=|r3|=0.7548776662466927600495088964<1
而且系数1/f'(r2)=-0.1553144148202335388809513556 - 0.3403615184218391572668216586i
|1/f'(r2)|= 0.3741236836573856033137177179
所以对于n>=1时,我们知道
|r2^(n+1)/f'(r2)+r3^(n+1)/f'(r3)|=2|r2^(n+1)/f'(r2)|<=2*|r2|^2|1/f'(r2)|<1/2
由此我们得知a(n)=round(r1^(n+1)/f'(r1))
HimeTale 2012-08-16
  • 打赏
  • 举报
回复
[Quote=引用 119 楼 的回复:]

取r为方程x^3-2x^2+x-1=0的唯一正根,即r~=1.754877666246692760049508896
于是通项为
a(n)=round(r^(n+1)/(3r^2-4r+1))
[/Quote]
能不能具体讲一下原因?
另外,牛顿迭代法好像只能求实根,不能求虚根。
mathe 2012-08-16
  • 打赏
  • 举报
回复
取r为方程x^3-2x^2+x-1=0的唯一正根,即r~=1.754877666246692760049508896
于是通项为
a(n)=round(r^(n+1)/(3r^2-4r+1))
sky2008444 2012-07-13
  • 打赏
  • 举报
回复
有没有人试过广度优先遍历? 很好做的啊
RiqueZhang 2012-07-12
  • 打赏
  • 举报
回复
鄙人不才,10楼的方程解不出来

[Quote=引用 111 楼 的回复:]

既然kyzaqlx大牛对矩阵这么熟练,
为啥不顺便讲讲通项公式的解法呢。
[/Quote]
加载更多回复(100)

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧