演算法-棧的出棧個數
阿新 • • 發佈:2019-01-04
import java.math.BigInteger; /** 問題描述: n個元素的出棧次序 f(n)=f(0)*f(n-1)+f(1)*f(n-2)...+f(n-2)*f(1)+f(n-1)*f(0) 輸出樣例: 0:1 1:1 2:2 3:5 4:14 5:42 6:132 7:429 8:1430 9:4862 10:16796 11:58786 12:208012 13:742900 14:2674440 15:9694845 16:35357670 17:129644790 18:477638700 19:1767263190 20:6564120420 * @author Vivinia */ public class StackNum { static BigInteger[] num=new BigInteger[101]; //使用陣列儲存之前計算過的資料 public static void main(String[] args) { for(int i=0;i<=100;i++) num[i]=BigInteger.valueOf(0); //先全部賦值為0 num[0]=BigInteger.valueOf(1); for(int i=0;i<=100;i++) System.out.println(i+":"+f(i)); } private static BigInteger f(int n) { BigInteger total=BigInteger.valueOf(0); if(n==0) return num[0]; //0是退出遞迴的邊界條件 if(num[n]!=BigInteger.valueOf(0)) return num[n]; //判斷以前是否計算過資料,如果計算過資料直接從陣列中取出,不用再次計算 for(int i=0;i<n;i++) total=total.add((f(i).multiply(f(n-i-1)))); //迴圈累加每次成績 num[n]=total; //將該次資料儲存起來 return total; } }
需要注意的地方:
1.首先找到通用公式f(n)=f(0)*f(n-1)+f(1)*f(n-2)...+f(n-2)*f(1)+f(n-1)*f(0),嗯,我從網上查的。。。
2.核心程式碼就是遞迴中的for迴圈語句,外加退出遞迴的return 1,但是如果只這樣遞迴,在n為16時就明顯感覺時間變慢,大約接近一秒鐘,然後往後時間為指數增長,到20就已經超過人的耐心等待時間了,這是因為每次計算一個數,都把前邊的資料重新算了一遍,做了很多無用功,所以定義一個數組把每次計算的資料儲存起來,以後先查詢陣列,陣列沒有儲存再計算;
3.雖然網上搜著long型資料很大,但是如果用long到n=20時就溢位了,所以改用BigInteger型,現在測試到100輸出都沒問題,而且時間很快,只不過就是不知道資料的資料對不對,反正很大。。。