CSDN英雄会题解之分巧克力与巨人网络笔试题之上台阶

随意翻论坛,翻到巨人网络的一道笔试题,感觉很熟悉。想到在CSDN遇到过。这两道题很相似,也很简单,都能很容易的想到动态规划递归,然后将其改成非递归实现提高效率。

分巧克力

题意大概是一块长度为n的巧克力,每次可以在边上砍去一段,这段的长度可以是1,也可以是2,问最后有多少种砍法?

显然是f(n)=f(n-1)+f(n-2),f(0)=1,f(1)=1,类似与斐波那契数列啊

代码:

#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
class Test {
public:
    static long long pre (int   x){
       /*递归方法 
	   if(1==x)return 1;
		if(2==x)return 2;
		return pre(x-1)+pre(x-2);
	*/
		//将递归改写为非递归
		if(1==x)return 1;
		if(2==x)return 2;
		long long x1=1,x2=2,x3=0;
		for(int i=3;i<=x;++i){
			x3=x1+x2;
			x1=x2;
			x2=x3;
		}
		return x3;
    }
};
//start 提示:自动阅卷起始唯一标识,请勿删除或增加。
int main(){   
    cout<<Test::pre(50)<<endl;   
} 
//end //提示:自动阅卷结束唯一标识,请勿删除或增加。

非递归实现辅助空间是2,因为只跟前两项有关。

巨人网络笔试题--上台阶

1, 假设A上台阶,一次可以跨1层,2层或3层,问A上50层台阶,有多少种走法?
假设A上台阶,一次可以跨1层,2层,3层.. 或m层,问A上n层台阶,有多少种走法?
其中,m和n都是正整数,并且 m <= n, m <= 10, n <= 50
请编程解决这个问题,并详细说明解题思路。

同样可以通过f(x)=f(x-1)+f(x-2)....+f(x-m),f(0)=1,f(1)=1;

可以通过递归和非递归实现,非递归实现的辅助空间为o(m),因为跟前m项相关,代码如下:

#include <iostream>
#include <vector>
int getNum1(int n,int m){
        if(0==n)
                return 1;
        int ret=0;
        int max=n>=m?m:n;
        for(int i=1;i<=max;++i)
                ret+=getNum1(n-i,m);
        return ret;
}
int getNum2(int n,int m){
        /*这里为了简单使用了n个辅助空间,当然可以通过循环使用m个辅助空间*/
        std::vector<int>*ret=new std::vector<int>(n+1);
        (*ret)[0]=1;
        for(int i=1;i<=n;++i){
                int max=m<=i?m:i;
                for(int j=1;j<=m&&j<=i;++j){
                        (*ret)[i]+=(*ret)[i-j];
                }
        }
        return (*ret)[n];
}
int main(int argc,char**argv){
        std::cout<<getNum1(3,2)<<std::endl;
        std::cout<<getNum2(3,2)<<std::endl;
        std::cout<<getNum1(10,3)<<std::endl;
        std::cout<<getNum2(10,3)<<std::endl;

        return 0;
}

优化

可以通过下面来减少加法次数:

f(x+m)=f(x+m-1)+....+(fx)

f(x+m+1)=f(x+m)+f(x+m-1)+....+(fx+1)  =2*f(x+m)-f(x)=(f(x+m)<<1)-f(x)来优化


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值