模拟经典的爬楼梯问题

声明:下面的代码很垃圾,效率极差,没有任何安全判断,只是讨论这个问题,拒绝从代码方面打击
模拟经典的爬楼梯问题
经典描述:一次最多爬2层,当有N层楼梯时候有多少种情况

程序:(低效的递归,容易溢出)

const double step1 = 1;
const double step2 = 2;
const double step3 = 4;

double GetStep2(unsigned int num)
{
    if (num == 1)
        return step1;
    else if (num == 2)
        return step2;
    else if (num > 2)
        return GetStep2(num - 1) + GetStep2(num - 2);
}

double GetStep3(unsigned int num)
{
    if (num == 1)
        return step1;
    else if (num == 2)
        return step2;
    else if (num == 3)
        return step3;
    else if (num > 3)
        return GetStep3(num - 1) + GetStep3(num - 2) + GetStep3(num - 3);
}

一次最多爬2层,我们需要预先定义两个常量,如上step1、step2表示1层楼梯的可能数和2层楼梯的可能数

同样:如果一次最多爬3层

step1 = 1;
step2 = 2;
step3 = 4;  // 1+1+1/1+2/2+1/3
// 预定义三个常量
如果一次最多爬M层,M<=N
我们需要预定义M个常量

std::map<int, double> step;
step[0] = 1;  // 一步可以跨完 M个台阶
step[1] = step[0];  
step[2] = step[1] + step[0];
step[3] = step[2] + step[1] + step[0];
.
.
.
.
step[M] = step[M - 1] + .... + step[0];
// 其实就是有N个台阶,最大可以一次走N个台阶的问题

double getConstStep(unsigned int M)
{
    if (M == 0)
	    return 1;
	else if (M > 0)
    {
        double result = 0.0;
        for (unsigned int i = 1; i <= M; ++i)
        {
            result += getConstStep(M - i);
        }
        return result;
	}
}
// 原谅我,节省代码,理解容易,又是一个递归

// 原来算爬楼梯可能性的代码改一下
double GetStep(unsigned int num)
{
    // if (num == 0 || M == 0 || num < M)
	//     exit(-1);
    if (step.find(num) != step.end())
	    return step[num];
    else
    {
        double result = 0.0;
        for (unsigned int i = 1; i <= M_; ++i)
        {
            result += GetStep(N - i);
        }
        return result;
	}
}

// 冒充C++的写法

class GetConst
{
public:
    std::map<int, double> theStepConst_;
    unsigned int M_;

public:
    GetConst(const unsigned int M)
    :M_(M)
    {

    }

    void FillStepConst()
    {
        for (unsigned int i = 1; i <= M_; ++i)
        {
            // 循环里面用递归,我一定是疯了
            theStepConst_[i] = GetStepConst(i);
        }
    }

    double GetStepConst(unsigned int theM)
    {
        if (theM == 0)
            return 1;
        else if (theM > 0)
        {
             double result = 0.0;
            for (unsigned int i = 1; i <= theM; ++i)
            {
				// 该死的循环递归
                result += GetStepConst(theM - i);
            }
            return result;
         }
    }


    double GetStepWithMN(unsigned int N)
    {
        /*
        if (N == 0 || M == 0 || N < M)
            return 0.0;
        */
        if (theStepConst_.find(N) != theStepConst_.end())  // 这个可以优化一下
            return theStepConst_[N];
        else
        {
            double result = 0.0;
            for (unsigned int i = 1; i <= M_; ++i)
            {
				// 该死的循环递归
                result += GetStepWithMN(N - i);
            }
            return result;
        }
    }
};

// 测试一下
    GetConst getConst(2);
    getConst.FillStepConst();
    cout << getConst.GetStepWithMN(10) << endl;
    cout  << "-------------------------------" << endl;  // 89

    cout << GetStep2(10) << endl;

    cout  << "-------------------------------" << endl;   // 89
    GetConst getConst(3);
    getConst.FillStepConst();
    cout << getConst.GetStepWithMN(10) << endl;
    cout  << "-------------------------------" << endl;   // 274

    cout << GetStep3(10) << endl;

    cout  << "-------------------------------" << endl;   // 274


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值