【题目描述】
把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
采用递归的方法
#include<bits/stdc++.h>
using namespace std;
int ans;
void dg(int m, int n){//m:苹果数 n:盘子数
if(m==0 || n==1)
ans += 1;
else if(m < n)
dg(m, m);
else if(m >= n){
dg(m-n, n);
dg(m, n-1);
}
return ;
}
int main(){
int t, m, n;
cin >> t;
while(t--){
cin >> m >> n;
ans = 0;
dg(m, n);
cout << ans << endl;
}
return 0;
}
采用回溯的方法
#include<bits/stdc++.h>
using namespace std;
int a[20];
int f(int m, int cnt, int n){//m:苹果数 cnt:第几个盘子 n:盘子数
int ans = 0;//局部变量,每一层都是重新定义,下一层的值通过return ans返回
if(m == 0 && n == 0)
return 1;
if(m != 0 && n == 0)
return 0;
for(int i=a[cnt-1]; i<=m; i++){//i:每个盘子的苹果数,从a[cnt-1]是为了防止1 1 5和5 1 1重复计算的情况
a[cnt] = i;//当前盘子存放的苹果树
ans += f(m-i, cnt+1, n-1);//递归
a[cnt] = 0; //回溯 标记清零
}
return ans;
}
int main(){
int t, n, m;
cin >> t;
while(t--){
cin >> m >> n;
cout << f(m, 1, n) << endl;
}
return 0;
}