一本通1222 放苹果

【题目描述】

把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<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
int dfs(int,int,int);
int r,m,n,ans=0;
int maxn[11];根据取值范围定义最大值数组 
int main()
{
cin >> r;
while(r --)
{
cin >> m >> n;
for(int i = 0;i < n;i ++)
maxn[i+1] = m / (n - i);//这个最大值求的很讲究,下一个数的最大值,是总数除以剩下的盘子,因为前面的盘子可能不放,所以有可能最后一个盘子放很多,这也是我一开始疏忽的,我一开始只是单纯的用总数除以盘子,但是这样做是不对的
cout << dfs(0,0,1) << endl;
}
return 0;
}
int dfs(int x,int y,int z)//x代表已经放完的苹果,y,z表示第z个盘子放了y个苹果
{
int ans = 0;//每次搜索都先定义ans为0
if(z == n&&m - x >= y)//如果已经搜索到最后一个盘子并且这个盘子可以放不多于前一个盘子的苹果(防止重复,就规定前面的盘子苹果大于等于后面盘子里的苹果),就返回1,加一种情况
return 1;
if(z == n)//反之,如果到了最后一个盘子但是不符合情况,就返回0,表示不可行
return 0;
for(int i = y;i <= maxn[z];i ++)//从当前开始枚举,小于等于最大值,并且不少于上一个盘子里的苹果
ans+=dfs(x+i,i,z+1);//继续搜索,总数加上这个盘子里放的苹果,搜索下一个盘子
return ans;//返回总情况
}

猜你喜欢

转载自www.cnblogs.com/57xmz/p/12585004.html