39级台阶问题

题目:第39级台阶

小明刚刚看完电影《第39级台阶》,离开电影院的时候,他数了数礼堂前的台阶数,恰好是39级!

站在台阶前,他突然又想着一个问题:
如果我每一步只能迈上1个或2个台阶。先迈左脚,然后左右交替,最后一步是迈右脚,也就是说一共要走偶数步。那么,上完39级台阶,有多少种不同的上法呢?

请你利用计算机的优势,帮助小明寻找答案。

要求提交的是一个整数。

程序分析:

这个程序不要纠结在左脚和右脚的问题上,从中抽象出限制条件:一共走的步数是偶数;

我们可通过递归来实现,对每次递归的结果进行判断,如果走过的台阶数为39,则递归结束,判断走的步数是否为偶数,为偶数则为上法计算器加一,否则为无效上法。

递归算法:

Java

    public class Test003 {  
          
        private static int count;  
          
        public static void main(String[] args) {  
            count = 0;  
            walkUp(0, 0);  
            System.out.println(count);  
        }  
          
        /** 
         * 模拟上台阶 
         *  
         * @param step 使用的步数,范围0-39 
         * @param tj 总过的台阶数,范围0-39 
         */  
        private static void walkUp(int step, int tj){  
            if(tj > 39){  
                return;  
            }  
              
            if(tj == 39){  
                if(step%2 == 0){  
                    count++;  
                }  
                return;  
            }  
              
            walkUp(step+1, tj+1);  
            walkUp(step+1, tj+2);  
        }  
          
    }  

C++

    #include<iostream>  
    using namespace std;  
    int count=0;  
    void fun(int stair,int step)  
    {   //stari用于表示剩余的楼梯的层数,当等于0时停止递归  
        //step是走过的步数,用来判断是否是偶数,是否符合要求  
         if(stair<0)return;   
         if(stair==0)   //39节楼梯全部走完   
         {  
            if(step%2 == 0)count++;  
            return;  
         }   
         fun(stair-1,step+1);   //这一步走了一个台阶   
         fun(stair-2,step+1);   //这一步走了两个台阶   
    }  
    int main()  
    {  
        fun(39,0);  
        cout<<count<<endl;  
        return 0;   
    }  

非递归算法:

package exercise;
/**
 * 39级台阶问题
 * @author Administrator
 *
 */
public class Main_exer {
    
    public static void main(String[] args) {  
    	 //动态DP思想
        //创建一个39*2数组的二维数组s[i][j]
        //i表示第N级台阶,j表示在该台阶上为左脚0,右脚1
        //s[i][j]表示在i级台阶,刚好为j脚,总共可能得情况个数
        int[][] s = new int[39][2];
        //定义初始值,数组是从0-38,表示1-39级台阶
        //以下四个初始值你都不理解得话,别学编程了
        s[0][0]=1;//第一级台阶,左脚的情况个数只有1次
        s[0][1]=0;//第一级台阶,右脚的情况个数只有0次,因为第一次漫的必定为左脚
        s[1][0]=1;//第二级台阶,左脚的情况个数只有1次
        s[1][1]=1;//第二级台阶,右脚的情况个数只有1次
        //循环计算
        for(int i = 2;i<39;i++){
            //s[i][0]的值刚好是s[i-1][1]的情况再漫左脚一个台阶,刚好到达s[i][0]
            //或者s[i-2][1]的情况再漫左脚两个台阶,刚好到达s[i][0]
            //所以s[i][0]的值等于以上两个之和
            s[i][0] = s[i-1][1] + s[i-2][1];
            //原理同上
            s[i][1] = s[i-1][0] + s[i-2][0];
        }
        for(int i=0;i<s.length;i++){
        	for(int j=0;j<s[0].length;j++){
        		System.out.print(s[i][j] + " ");
        	}
        	System.out.println();
        }
    }  
    
}
参考: http://blog.csdn.net/bear_huangzhen/article/details/50068077

http://ask.csdn.net/questions/346001

http://blog.csdn.net/qsyzb/article/details/18991233

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值