題目:B - 小兔的棋盤
小兔的叔叔從外面旅遊回來給她帶來了一個禮物,小兔高興地跑回本身的房間,拆開一看是一個棋盤,小兔有所失望。不過沒過幾天發現了棋盤的好玩之處。從起點(0,0)走到終點(n,n)的最短路徑數是C(2n,n),如今小兔又想若是不穿越對角線(但可接觸對角線上的格點),這樣的路徑數有多少?小兔想了很長時間都沒想出來,如今想請你幫助小兔解決這個問題,對於你來講應該不難吧!
Input
每次輸入一個數n(1<=n<=35),當n等於-1時結束輸入。
Output
對於每一個輸入數據輸出路徑數,具體格式看Sample。
Sample Input
1
3
12
-1
Sample Output
1 1 2
2 3 10
3 12 416024ios
思路:這個題要特別注意一下里面有個要求即不能越過對角線!,因此能夠分開處理,即將其分紅上半邊和下半邊。只須要求出一個半邊,以後乘2便可。
這個題一開始我想進行組合來着,可是後來發現由於不能越過對角線,因此不能夠進行組合,因此就用相似斐波那契數列進行,即每次到一個格子的的方式的數量由走到下一個格子和走到左一個格子的方式的數量之和。而對角線由於特殊因此要單獨處理,即走到對角線的方式的數量僅有下邊一個格子決定,每次都要算到(n,n),即每次循環存儲的時候都要到(i,i);spa
新技巧:這個類斐波那契數列存數的方式早就接觸到,但這個是一種能夠用的狀況,即行走的步數的問題,即從這裏走怎麼走到另外一個問題,因此從每一步的種類數量由前一步仍是前幾步決定。
因此,總得來講就是,這種走路方式和數量的問題均可以嘗試用類斐波那契數列處理,前提必需要有先後關係才行!!code
代碼:ci
#include<iostream> #include<cstring> using namespace std; long long a[37][37]; int main() { int i,j,n; memset(a,0,sizeof(a)); for(i=1;i<36;++i){ a[i][0]=1; for(j=1;j<i;++j){ a[i][j]=a[i-1][j]+a[i][j-1]; } a[i][i]=a[i][i-1]; } int num=0; while(cin >> n&&n!=-1){ num++; cout << num << " " << n << " "<< 2*a[n][n] << endl; } return 0; }