最近找工作参加了bilibili的笔试,题目难度一般,然而发现自己好久没有做个编程题了居然不知道怎么处理输入了。哎实在是太菜了。不过其中遇到一个题觉得很有意思
问题:你有10颗糖,一天至少吃一颗,请问有多少种吃法?
题目很简单,就是普通的插板法就可以解决。10颗糖每天至少吃一颗,那么就有9个插孔,9个插孔可插可不插,所以结果是2^9=512种吃法。
这个题让我想起了青蛙跳台阶的问题:
问题1:已知一只?一次可以跳1阶或2阶的台阶,请问跳上N阶台阶有多少种跳法?
问题2:这只?进化了,现在可以一次跳1~N阶的台阶,请问现在跳上N阶台阶有几种跳法?
问题3:hape?又退化了,现在可以一次跳1~X阶的台阶(X<N),请问这只hape?现在跳上N阶台阶有多少种跳法?
问题1的思路如下:
- 只有1阶台阶,就只有一种跳法,f(1)=1;
- 有2阶台阶,那么现在就有两种跳法[{1,1},{2}],即f(2)=2;
- 当台阶数大于2时,那么第一步就有两种情况了:(1)第一步跳一阶台阶,那么接下来还有n-1阶台阶要跳,(2)第一步跳两阶台阶,那么接下来还有n-2阶台阶要跳,所以f(n)=f(n-1)+f(n-2)
这是一个斐波那契数列,答案也就出来啦,至于斐波那契数列的编程实现也就不做解析了,可以用递归法去做,在处理的过程中最好用数组保存结果,这样算法不用每次求都去计算结果啦。
问题2的思路如下:
我们用a表示1阶台阶,|表示挡板,挡板之间的a的个数代表每次跳的阶梯数,那么就有:
a|a|a|a|a|a|a|a|a|a
第一个挡板我们可以放置也可以不放置,所以有两种选择,接下来的挡板也是如此,那么10阶台阶,就有9个挡板,所以问题二的答案就是2^(n-1)种跳法。
看到问题三,问题三是我突然想到如何在给定x(青蛙最大跳跃步数)和n(台阶数),求得通式。
起初我对问题三不知所措,感觉很复杂,仔细一想,发现这就是问题1和问题2的结合版呀。首先我们从问题一中可以看到青蛙在决定第一步跳的台阶数m,剩下的台阶的跳法就是f(n-m),所以f(n)=f(n-1)+f(n-2)+f(n-3)+···+f(n-x),而f(1),f(2),f(x)我们已经通过第二步已经做出来了结果是2^(x-1)。
那么,我们可以推导其公式为:
f(a)=2^(a-1) a<x
f(a)=f(a-1)+f(a-2)+···+f(a-x) x<a<n (TAT不会用这个插入公式)
问题到此也结束啦,至于算法有了推导公式之后也就不难了呀。这个题目也告一段落啦!
如果有错误,敬请指正!