多維算法思考(三):AB組合問題 算法
題目:x個A,y個B能夠組合成多少個不一樣排列的問題。數組
首先,咱們用數學的方式思考,這個問題屬於《組合數學》的問題,咱們的第一種方法能夠用組合思路來求解。spa
也就是說在x+y個單元格中隨機選出x個單元格用來存放A,那麼其餘的也就天然存放B,因此共有種不一樣的排列,例如當x=3,y=2時,可組成10種不一樣的排列。 code
這種方法雖好,但不直觀。若是咱們要列出全部的AB組合,這種方法顯然不容易辦到,這時咱們能夠用另外一種方法來求解。利用遞歸的思想。咱們用f(x,y)表示x個A,y個B能夠組合成的不一樣排列數,則當第一個是A時,共有f(x-1,y)種不一樣排列數,當第一個是B時,共有f(x,y-1)種不一樣排列數。因此f(x,y)=f(x-1,y)+f(x,y-1)。orm
也許有人會問,這樣一個遞歸式子,咱們不是同樣看不出來AB組合嗎?確實,從表面看,咱們也不能直觀的列出AB組合。這是咱們須要對其變通一下,將它轉換成樹狀圖。下面咱們仍是以x=3,y=2爲例:xml
x每減一,樹枝上就會多一A;y每減一,樹枝上就會多一B。若x或y爲0,則結束,剩下的數字即爲B或A的個數。上述AB組合從左到右依次爲AAABB--AABAB--AABBA--ABAAB--ABABA--ABBAA--BAAAB--BAABA--BABAA--BBAAA共可組成10種不一樣的排列。 blog
下面咱們用C語言來實現上述遞歸算法。(遞歸執行順序圖以下)遞歸
算法思路:原理同上述樹狀執行圖。咱們先設兩個全局變量p,q,初始值p=x,q=y。經過每一次x與p,y與q的大小比較來判斷執行的流程。 數學
當x=0或y=0時結束。用數組a[5]來記錄執行過程當中AB的順序。io
完整算法:
//x個A,y個B能夠組合成多少個不一樣排列的問題 #include<stdio.h> #define x 4 #define y 2 int p=x,q=y,k=0; char a[5]; int fun(int m,int n) { if(m<p) { a[k++]='A'; p=m; q=n; if(m==0) { for(int j=0;j<k;j++) printf("%c",a[j]); for(int i=0;i<n;i++) printf("B"); printf("\n"); k--; p++; return 1; } } else if(m>p) { for(int i=p;i<m;i++) k--; p=m; if(q==n) { q++; k--; } } if(n<q) { a[k++]='B'; p=m; q=n; if(n==0) { for(int j=0;j<k;j++) printf("%c",a[j]); for(int i=0;i<m;i++) printf("A"); printf("\n"); k--; q++; return 1; } } else if(n>q) { for(int i=q;i<n;i++) k--; q=n; if(p==m) { p++; k--; } } return fun(m-1,n)+fun(m,n-1); } void main() { printf("\n%d個A,%d個B可組成%d種不一樣的排列\n",x,y,fun(x,y)); }
執行效果圖: