放橘子
1.题目
【题目描述】
把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
2.分析
这道题一看就是需要使用递归,写递归函数首先要确定终止条件:当橘子没有了的时候无论盘子有几个都只有一种方法,当盘子只有一个的时候无论橘子有几个都只有一种方法,所以终止条件就是:
if(orange==0||plate==1){
return 1;
}
//在我的程序中用n表示orange,用m表示plate
如果没到这个终止条件,函数就要继续,因为题目说允许有盘子空着,所以分为两大类:有盘子空着的和没盘子空着的
有盘子空着的话,橘子数量是不变的,而盘子会减少一个,因为那个里面什么都没放,所以这种情况的函数调用这样写:
dfs(orange,plate-1);
//在我的程序中用n表示orange,用m表示plate
没有盘子空着的话,每次给每个盘子里放一个橘子,这样橘子数量会减少盘子个,而盘子不会变,所以这种情况函数调用这样写:
dfs(orange-plate,plate);
//在我的程序中用n表示orange,用m表示plate
这样大部分情况就考虑好了:
dfs(orange,plate-1)+dfs(orange-plate,plate);
//在我的程序中用n表示orange,用m表示plate
但是很容易忽略一种特殊情况,也就是橘子数量小于盘子数量的情况。这种情况其实就是橘子数量的橘子放到橘子数量的盘子里,因为每个盘子里放1个橘子这种情况是极端的,最多只会用掉橘子数量个盘子,代码这样写:
if(orange<plate){
dfs(orange,orange);
}
//在我的程序中用n表示orange,用m表示plate
这样所有情况就差不多啦,不要忘记可能有多组数据哦~
3.完整代码
#include<bits/stdc++.h>
using namespace std;
int dfs(int n,int m){
if(n==0||m==1)
return 1;
if(n<m)
return dfs(n,n);
else
return dfs(n,m-1)+dfs(n-m,m);
}
int main(){
int T,o,p;
cin>>T;
for(int i=1;i<=T;i++){
cin>>o>>p;
cout<<dfs(o,p)<<endl;
}
return 0;
}
制作不易,点个赞吧😘