方块与收纳盒_走楼梯

27 篇文章 1 订阅
17 篇文章 0 订阅

题目描述

现在有一个大小n*1的收纳盒,我们手里有无数个大小为1*1和2*1的小方块,我们需要用这些方块填满收纳盒,请问我们有多少种不同的方法填满这个收纳盒
  输入描述:

第一行是样例数T 第2到2+T-1行每行有一个整数n(n<=80),描述每个样例中的n。   输出描述:

对于每个样例输出对应的方法数。   示例1 输入

3 1 2 4   输出

1 2 5   说明

n=4,有五种方法 1:1 1 1 1
3:1 2 1
4:1 1 2
5:2 2

1
2
3
4
5
6

备注:

对于100%的数据, 0 < T < 80; 0 < n <= 80。

这道题和走n阶楼梯是一样的, 使用递推的方法. 答案就是斐波那契数列.

如何理解?

当走第n阶楼梯时, 我们可以知道从上一步到这一步有两种可能, 一是从n-1阶楼梯跨了一步来的, 另一种可能是从n-2阶楼梯跨了2步来的. 所以方法为Fn-1 + Fn-2. 知道1, 2阶楼梯的方法即可递推得到.

#include <iostream>
using namespace std;

int main( )
{
    int t, n;
    cin >> t;
    while( t-- ) {
        cin >> n;
        long long a[3] = {3, 1, 2};
        for( int i = 4; i <= n; ++i ) 
        {
            a[i%3] = a[(i-1)%3] + a[(i-2)%3];
        }
        cout << a[n%3] << endl;
    }
}

总结: 要善于观察和推导. 我在思考的过程中想了用递归的方法, 每次走一步或两步, 结果空间太大了. 其实其中的思想就是递推.

还想了用数学里面的组合方法, 枚举所有可能的1步或两步情况, 再计算每一种情况的情况.

垃圾代码如下:

#include <iostream>
#include <algorithm>
using namespace std;

int main( )
{
    int t, n;
    cin >> t;
    while( t-- ) {
        cin >> n;
        unsigned long long ans = 0;
        for( int i=0;i<=n; ++i) {
            if(n%2==0 && i%2==1) continue;
            if(n%2==1 && i%2==0) continue;
            unsigned long long all = i + (n-i)/2;
            unsigned long long tmp = 1, temp = 1;
            int k = min((unsigned long long)i, all-i);
            for( int j = all; j>=all-k+1; --j ) {
                tmp *= j;
            }
            for( int j = 1; j<=k; ++j) {
                temp *= j;
            }
            ans += tmp/temp;
        }
        cout << ans << endl;
    } 
}

通过了50%的样例.
大概是因为这种方法得到的中间量可能超范围.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值