poj1664放苹果(递归)
题目链接: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 }