题目链接:http://poj.org/problem?id=1664
放苹果
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 37273 | Accepted: 22957 |
Description
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
Input
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。
Output
对输入的每组数据M和N,用一行输出相应的K。
Sample Input
1 7 3
Sample Output
8解题思路:就是n个球放m个盒子的问题,采用递归的思想,定义函数func(n,m)为n个苹果放入m个盘子,可以分为两种情况:第一种,当m>n, 则总会有m-n个盒子空着,去掉他们对总的放法不产生影响,即 if(m > n) f(n, m) = f(n, n)第二种,当n<=m时,可以分为两种: 1.至少有一个盒子空着,则 f(n, m) = f(n, m-1); 2.所有盒子都有球,我们可以从每个盒子中拿掉一个球而不影响总的放法,则 f(n, m) = f(n-m, m);所以当n<=m时,f(n, m)=f(n, m-1) + f(n-m, m)还有很多种不一样的n个球放入m个盒子的问题,这篇博客写的很详细:https://blog.csdn.net/zwz_511/article/details/46240927递归出口的话看大佬解释的感觉很有道理,递归出口条件说明: 当m=1时,所有苹果都必须放在一个盘子里,所以返回1; 当没有苹果可放时,定义为1种放法; 递归的两条路,第一条m会逐渐减少,终会到达出口m==1; 第二条n会逐渐减少,因为m>n时,我们会return func(n,n) 所以终会到达出口n==0附上代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 int ans,n,m; 6 7 int func(int n,int m) 8 { 9 if(m==1||n==0) return 1; 10 if(m>n) return func(n,n); 11 return func(n,m-1)+func(n-m,m); 12 } 13 14 int main() 15 { 16 int t; 17 cin>>t; 18 while(t--) 19 { 20 cin>>n>>m; 21 ans=func(n,m); 22 cout<<ans<<endl; 23 } 24 return 0; 25 }
来源:https://www.cnblogs.com/zjl192628928/p/9439674.html