数的划分 | ||||||
| ||||||
Description | ||||||
将整数n分成k份,且每份不能为空,任意两份不能相同(不考虑顺序)。 例如:n=7,k=3,下面三种分法被认为是相同的。 1,1,5; 1,5,1; 5,1,1; 问有多少种不同的分法。 | ||||||
Input | ||||||
有多则测试数据。 对于每组测试数据,仅有一行,包括两个整数n,k (6<n<=200,2<=k<=6)。 | ||||||
Output | ||||||
对于每组测试数据,输出一个整数,即不同的分法。 | ||||||
Sample Input | ||||||
7 3 | ||||||
Sample Output | ||||||
4 | ||||||
Hint | ||||||
输入: 7 3 输出:4 {四种分法为:1,1,5; 1,2,4; 1,3,3; 2,2,3;} | ||||||
Source | ||||||
NOIp2001高中组 | ||||||
Recommend | ||||||
黄李龙 |
果然菜的抠脚~
题目分析:一开始想用dfs来做,用set和sort去重,失败了~ 后来百度看了别人的才知道原来这样做 ↓
这样考虑假设 sum(n,m) 为和为n的m个元素组成的所有可能,按题目要求无论n和m是多少,都会分成两种情况:
1、这个集合中至少含有一个1。2、这个集合中不含有1。
即 sum(n,m) = sum(n-1,m-1) + sum(n-m,m) 我们可以举个栗子
**这样的话还是很难理解,我们假设有7个小球3个箱子,不允许有空箱子。sum(6,2)表示的是至少有一个箱子中是1个球,既然知道某个箱子肯定有1个球,那我们只需要把6个小球放到剩下的2个箱子中就可以了,sum(4,3)表示的是因为所有箱子中球的数目都大于1,我们先把3个小球放入箱子中即n-m,然后在将剩下的4个球放入3个箱子中即可。**
代码:
#include<iostream>
using namespace std;
int Sum(int n,int m){
if(n<m) return 0; //出现空箱子
else if(m==1) return 1;
else if(n==m) return 1;
else return Sum(n-1,m-1)+Sum(n-m,m);
}
int main(){
int n,m;
while(cin>>n>>m)
cout<<Sum(n,m)<<"\n";
}