将整数n分成k份,且每份不能为空,任意两种划分方案不能相同(不考虑顺序)。
例如:n=7,k=3,下面三种划分方案被认为是相同的。
1 1 5
1 5 1
5 1 1
问有多少种不同的分法。
* 本题类似n个苹果放入m个盘子中
* 此基础上加入盘子不能为空
* 思路:
* m个苹果放在n个盘子中,那么定义函数为apple(m,n):
* 1.m=0,没有苹果,那么只有一种放法,即apple(0,n)=1
* 2.n=1,只有一个盘中,不论有或者无苹果,那么只有一种放法,apple(m,1)=1
* 3.n>m,和m个苹果放在m个盘子中是一样的,即apple(m,n)=apple(m,m)
* 4.m>=n,这时分为两种情况:
* 一、所有盘子都有苹果。
* 二、不是所有盘子都有苹果。
* 不是所有盘子都有苹果和至少有一个盘子空着是一样的,即=apple(m,n-1)。
* 所有盘子都有苹果,也就是至少每个盘子有一个苹果,
* m个苹果中的n个放在n个盘子中,剩下的m-n个苹果,
* 这和m-n个苹果放在n个盘子中是是一样的,即=apple(m-n, n)。
* 这时,apple(m,n)=apple(m-n, n)+apple(m,n-1)。
#include <cstdio> #include <iostream> using namespace std; int n, k; //a个苹果放入b个盘子中 int dfs(int a, int b) { //没有苹果 和 只有一个盘子 if(a == 0 || b == 1) return 1; else if(a < b) //苹果数 < 盘子数 等价于 苹果数 == 盘子数 return dfs(a, a); else //(无空盘)先b果放b盘,再a-b果放b盘 + (至少有1个空盘)a果放b-1盘 return dfs(a-b, b) + dfs(a, b-1); } int main() { cin>>n>>k; cout<<dfs(n-k, k); //先每个盘子放个苹果 就保证盘子不为空 return 0; }