描述:把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 <fstream>
#include<algorithm>
using namespace std;
int Count;
int a[11];//a[i]表示第i个盘子分的苹果个数
int sum;
int m,n;
int min(int x,int y)
{
return x<=y?x:y;
}
void Try(int j,int i) //尝试在剩余了j个苹果的情况下给第i个盘子分苹果
{
if(i>n) return ;
for(int k=min(a[i-1],j);k>=1;k--)
{
a[i]=k; sum=sum+k; //第i个盘子分k个苹果,sum表示已分苹果的总数
if(sum==m) //一种分法
{
Count++; //分法数加1
}
else Try(j-k,i+1);
sum=sum-k;
}
}
int main()
{
int t;
cin>>t;
for(int i=1;i<=t;i++)
{
cin>>m>>n;
Count=0;
if(n==1) //一个盘子只有一种分法
{
Count=1;
cout<<Count<<endl;
continue;
}
for(a[1]=m;a[1]>=1;a[1]--)
{//枚举第一个盘子分配苹果的个数
sum=a[1];
if(a[1]==m)
{
Count++;
}
Try(m-a[1],2); //在已知第一个盘子分完苹果的情况下从第2个盘子开始分苹果
}
cout<<Count<<endl;
}
return 0;
}
第二种方法:可计算放苹果方案数也可以输出每一种放法。
#include <stdio.h>
#include <stdlib.h>
int resu[20];
int f(int m,int n,int x)
{//m个苹果,n个盘子,且第一个盘子至少放x个苹果的分法数
int sum=0;
if(n==1)
{
resu[0]=m;//最后一个盘子放m个苹果
int j=0;
while(resu[j]!=-1) //输出一种放苹果方案
{ printf("%d ",resu[j]);j++;}
printf("\n");
return 1; //如果只有一个盘子,分法数为1(递归出口)
}
for(int i=x;i<=m/2;i++) //第一个盘子可以放x~m/2个苹果
{
resu[n-1]=i;
if(m-i>=i) sum+=f(m-i,n-1,i);//保证后分配苹果的盘子上苹果数量大于等于前一个盘子苹果数
}
return sum;
}
int main()
{
int n;
scanf("%d",&n);
int a,b; //苹果数和盘子数
while(n--)
{
scanf("%d%d",&a,&b);
resu[b]=-1;
printf("%d\n",f(a,b,0));
}
return 0;
}
2462

被折叠的 条评论
为什么被折叠?



