例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]; } }
方法三: