有M個小孩到公園玩,門票是1元。其中N個小孩帶的錢爲1元,K個小孩帶的錢爲2元。售票員沒有零錢,問這些小孩共有多少種排隊方法,使得售票員總能找得開零錢。注意:兩個拿一元零錢的小孩,他們的位置互換,也算是一種新的排法。(M<=10)spa
時間限制:1 sios
空間限制:128 M算法
有M個小孩到公園玩,門票是1元。其中N個小孩帶的錢爲1元,K個小孩帶的錢爲2元。售票員沒有零錢,問這些小孩共有多少種排隊方法,使得售票員總能找得開零錢。注意:兩個拿一元零錢的小孩,他們的位置互換,也算是一種新的排法。(M<=10)spa
輸入一行,M,N,K(其中M=N+K,M<=10).code
輸出一行,總的排隊方案。blog
4 2 2遞歸
8隊列
思路:思路挺簡單的,先無論每一個小孩的不同,先算出來總共排列有多少種,再乘以 n 和 k 的階乘就是答案了(乘以 n 和 k 的階乘就是把 1 和 2 全排列),至於怎麼算出來排列的種類,用遞歸算出來就能夠了。ci
代碼:io
1 #include <iostream> 2 #include <cstdio> 3 4 using namespace std; 5 int m, n, k, sum; 6 7 int fun(int ye, int nn, int kk) // ye表示餘額,nn表示1元小孩人數,kk表示2元剩餘人數 8 { 9 if(ye < 0) return 0; //餘額小於零,隊列無效 10 if(!nn && !kk) return 1; //某個量排完,剩餘位置只能排剩餘的種類,由於這裏n >= k 11 //保證剩下的排列合法,不會出現如:1 1 2 2 2 2 2 這種不合法的狀況 12 if(!ye) return fun(ye + 1, nn - 1, kk); //餘額爲零,因此下一位只能排1元的位置 13 return (fun(ye + 1, nn - 1, kk) + fun(ye - 1, nn, kk - 1)); //每次每一個位置能排 1 和 2 兩種類型的位置 14 } 15 int main() 16 { 17 cin >> m >> n >> k; 18 if(n < k) cout << "0"; //1的數量比2少的話不可能出現合法序列 19 else 20 { 21 sum = fun(1, n - 1, k); //保證第一位必定排1,否則隊列不合法 22 int x1, x2; 23 x1 = x2 = 1; 24 for(int i = 1; i <= n; i ++ ) x1 *= i; 25 26 for(int i = 1; i <= k; i ++ ) x2 *= i; 27 28 sum = sum * x1 * x2; 29 cout << sum; 30 } 31 return 0; 32 }
PS:還有一種更快的算法,卡特蘭數,百度出來的,呃,我也不太會,感興趣的能夠看下class