1222:放苹果

题目来源:http://ybt.ssoier.cn:8088/problem_show.php?pid=1222

1222:放苹果


时间限制: 1000 ms         内存限制: 65536 KB
提交数: 2382     通过数: 1636 

【题目描述】

把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。

【输入】

第一行是测试数据的数目t(0 ≤ t ≤ 20)。以下每行均包含二个整数M和N,以空格分开。1≤M,N≤10。

【输出】

对输入的每组数据M和N,用一行输出相应的K。

【输入样例】

1
7 3

【输出样例】

8

解析:
数学意义上讲,这道题属于整数划分。
引自百度:
指把一个正整数n写成多个大于等于1且小于等于其本身的整数的和,则其中各加数所构成的集合为n的一个划分。这是一个典型的递归算法。
所谓整数划分,是指把一个正整数n写成为
 
 
其中,   为正整数,并且
   
   
为n的一个划分。如果 
 
中的最大值不超过m,即
   
,则称它属于n的一个m划分。
解法:
这里我们记n的m划分的个数为  。例如,当n=4时,有5个划分,即
 
  
  
  
  
注意:  和
   
被认为是同一个划分。
根据n和m的关系,考虑一下几种情况:
(一)当  时,无论m的值为多少
   
,只有一种划分,即
   
(二)当  时,无论n的值为多少,只有一种划分,即n个1,
   
(三)当  时,根据划分中是否包含n,可以分为以下两种情况:
(1)划分中包含n的情况,只有一个,即 。
(2)划分中不包含n的情况,这时划分中最大的数字也一定比n小,即n的所有  划分。因此 。
(四)当  时,由于划分中不可能出现负数,因此就相当于
   
(五)当  时,根据划分中是否包含最大值m,可以分为以下两种情况:
(1)划分中包含m的情况,即  ,其中
   
的和为n-m,因此这种情况下为
 
(2)划分中不包含m的情况,则划分中所有值都比m小,即n的  划分,个数为
 
。因此
   
 
emmmmm....
 
这就是递归式。
 
参考代码:
 1 #include<cstdio>
 2 #include<cmath>
 3 #include<iostream>
 4 #include<cstring>
 5 using namespace std;
 6 int n,k;
 7 int dfs(int a,int p)
 8 {
 9                       //这里很巧妙,找到了当苹果为0时作递归边界 
10     if(a==0) return 1;//若没有苹果时,只有一种分法 
11     if(p==1) return 1;//只有一个盘子,也是仅一种分法 
12     if(a<p) return dfs(a,a);//尽可能压缩计算量,盘子数多于苹果数并无意义 
13     return dfs(a,p-1)+dfs(a-p,p);
14 }
15 int main()
16 {
17     int t;
18     cin>>t;
19     for(int i=0;i<t;i++)
20     {
21         cin>>n>>k;
22         cout<<dfs(n,k)<<endl;
23     }
24     return 0;
25 }

2019-03-28 19:19:17

猜你喜欢

转载自www.cnblogs.com/DarkValkyrie/p/10617077.html