題目描述ios
把M個一樣的蘋果放在N個一樣的盤子裏,容許有的盤子空着不放,問共有多少種不一樣的分法?(用K表示)5,1,1和1,5,1 是同一種分法。算法
輸入spa
每一個用例包含二個整數M和N。0<=m<=10,1<=n<=10。<=n<=10<=m<=10code
樣例輸入blog
7 3遞歸
樣例輸出ci
8io
/**class
* 計算放蘋果方法數目stream
* 輸入值非法時返回-1
* 1 <= m,n <= 10<><= m,n <= 10<>
* @param m 蘋果數目
* @param n 盤子數目數
* @return 放置方法總數
*
*/
public static int count(int m, int n)
思路:
1.利用遞歸思想,假設已經獲得後面一個盆子的擺放組合次數;
2.由於題目要的是組合,所以要把一樣重複的組合去掉,有一種辦法就是把盤子從左往右排一列,蘋果的數量依次爲降序,便可避免出現重複的狀況,所以要有個判斷。
3.結束條件要判斷當前是否知足降序,知足即知道該組合成立,返回1;不然返回0.
1 #include <iostream> 2 using namespace std; 3 4 int count(int m,int n,int b) 5 { 6 //結束條件 7 if(n==1) 8 { 9 if(m<=b) 10 return 1; 11 else 12 return 0; 13 } 14 15 //遞歸 16 int num=0; 17 for(int i=m;i>=0;i--) 18 { 19 if(i<=b) 20 num=num+count(m-i,n-1,i); 21 } 22 return num; 23 } 24 25 int main() 26 { 27 int m,n; 28 cin>>m>>n; 29 int num=count(m,n,m); 30 cout<<num<<endl; 31 }
在寫該算法過程當中,我開始的思路是先算出全部的排列次數,而後除掉重複的。但後來發現本身沒找到如何去除重複的排列的方法。由於有些排列重複的次數和其它排列重複的次數不同。下面是錯誤的算法。
1 #include <iostream> 2 3 using namespace std; 4 5 int count(int m,int n) 6 { 7 if(n==1) 8 { 9 return 1; 10 } 11 12 int num=0; 13 for(int i=m;i>=0;i--) 14 { 15 num=num+count(m-i,n-1); 16 } 17 return num; 18 } 19 20 int mul(int n) 21 { 22 int result=1; 23 for(int i=n;i>=1;i--) 24 { 25 result=result*i; 26 } 27 return result; 28 } 29 30 int main() 31 { 32 int m,n; 33 cin>>m>>n; 34 int num=count(m,n); 35 num=num/mul(n); 36 cout<<num; 37 }