例3:一共有10级,每次可走一步也能够走两步.必需要8步走完10级楼梯. 问:一共有多少种走法?html
分析:走一步的须要6次,走两步的须要2次。所以,本题是6个一、2个2的组合问题。在6个一步中,插入2个两步的,因可放在第一个1步以前,也能够放在最后一个1步以后,因此6个1步有7个空.所以,若是两个两步在一块儿有c(7,1)种;若是两个两步的分开来插有C(7,2)种,所以共有 c(7,1)+c(7,2)=7+21=28(种)=C(8,2)=C(8,6)
总数=8步中选2中走两步的=8步中选6个走一步的
Java编程实现:(数组迭代,动态规划,递归)java
package com.test;算法
public classzoutaijie {编程
// 梯有N阶,上楼能够一步上一阶,也能够一次上二阶。编一个程序,计算共有多少种不一样的走法。若是上20阶会有几种走法数组
public staticlongresult[]=new long[100];url
public staticvoidmain(String[] args) {spa
result[0]=result[1]=1;.net
for(inti=2;i<</span>result.length;i++)htm
result[i]=-1;blog
//s不能太大,不然int溢出
int s =60;
//动态规划
long startTime = System.currentTimeMillis();
System.out.println("动态规划解决:"+fun1(s));
long endTime = System.currentTimeMillis();
System.out.println("动态规划解决-程序运行时间:"+(endTime-startTime)+"ms");
//数组叠加
long startTime2 = System.currentTimeMillis();
System.out.println("数组叠加实现:"+fun2(s));
long endTime2 = System.currentTimeMillis();
System.out.println("数组叠加实现-程序运行时间:"+(endTime2-startTime2)+"ms");
//递归方法
long startTime1 = System.currentTimeMillis();
System.out.println("递归方法解决:"+fun(s));
long endTime1 = System.currentTimeMillis();
System.out.println("递归方法解决-程序运行时间:"+(endTime1-startTime1)+"ms");
}
public staticlongfun(ints){
if(s==0 || s==1)
return 1;
else{
return fun(s-1)+fun(s-2);
}
}
public staticlongfun1(ints){
if(result[s]>=0) {
return result[s];
}else{
result[s]=(fun1(s-1)+fun1(s-2));
return result[s];
}
}
public staticlongfun2(ints){
long result_1[]=newlong[s+1];//注意这个要大一个,多了个第0个
result_1[0]=result_1[1]=1;
for(inti=2;i<=s;i++)
result_1[i]=result_1[i-1]+result_1[i-2];
return result_1[s];//s就是第s+1个
}
}
分析:
(1) int s=48时候的运行效果:
(2). int s=60时候的运行效果
显然数组叠加和动态规划效率高不少不少,不是一个数量级的!
/**
* 功能:有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次能够上1阶、2阶或3阶。计算小孩上楼梯的方式有多少种。
*/
三种方法:
方法一:
//递归法 /** * 思路:自上而下的方式。 * 最后一步多是从第n-1阶往上走1阶、从第n-2阶往上走2阶或从第n-3阶往上走3阶。 * 所以,抵达最后一阶的走法,抵达这最后三阶的方式的综合。 * @param n * @return */ public static int countWays(int n){ if(n<0) return 0; else if(n==0)//注意此处条件 return 1; else{ return countWays(n-1)+countWays(n-2)+countWays(n-3); } }
方法二:
//动态规划 /** * 思路:每次调用都会分支出三次调用。予以动态规划加以修正。 * @param n * @param map * @return */ public static int countWaysDP(int n,int[] map){ if(n<0) return 0; else if(n==0) return 1; else if(map[n]>-1) return map[n]; else{ map[n]=countWaysDP(n-1,map)+countWaysDP(n-2,map)+countWaysDP(n-3, map); return map[n]; } }
方法三: