放苹果
题目描述
把 m m m 个同样的苹果放在 n n n 个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法。( 5 , 1 , 1 5,1,1 5,1,1 和 1 , 1 , 5 1,1,5 1,1,5 是同一种方法)
输入格式
第一行是测试数据的数目 t t t,以下每行均包括二个整数 m m m 和 n n n,以空格分开。
输出格式
对输入的每组数据 m m m 和 n n n,用一行输出相应的结果。
样例 #1
样例输入 #1
1
7 3
样例输出 #1
8
样例 #2
样例输入 #2
3
3 2
4 3
2 7
样例输出 #2
2
4
2
提示
对于所有数据,保证: 1 ≤ m , n ≤ 10 1\leq m,n\leq 10 1≤m,n≤10, 0 ≤ t ≤ 20 0 \leq t \leq 20 0≤t≤20。
【算法分析】
当苹果数<=盘子数时,问题转化为i个苹果放到i个盘子里。
当苹果数>盘子数时,分为两种情况:(1)无空盘,(2)有空盘
【递推算法分析】
使用i和j分别表示苹果数和盘子数,建立表格如下:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
3 | 1 | 2 | 3 | 3 | 3 | 3 | 3 | 3 |
4 | 1 | 3 | 4 | 5 | 5 | 5 | 5 | 5 |
5 | 1 | 3 | 5 | 6 | 7 | 7 | 7 | 7 |
6 | 1 | 4 | 7 | 9 | 10 | 11 | 11 | 11 |
7 | 1 | 4 | 8 | 11 | 13 | 14 | 15 | 15 |
8 | 1 | 5 | 10 | 15 | 18 | 20 | 21 | 22 |
(1)当盘子数为1时,只有一种情况。
(2)当苹果数为1时,只有一种情况。
(3)当苹果数<=盘子数时,问题转化为i个苹果放在i个盘子中,即 f [ i ] [ j ] = f [ i ] [ i ] = f [ i ] [ i − 1 ] f[ i][ j ]=f[i][i]=f[i][i-1] f[i][j]=f[i][i]=f[i][i−1]。
(4)当苹果数>盘子数时,分为两种情况:
- 不需要有盘子为空,即 f [ i − j ] [ j ] f[i-j][j] f[i−j][j]。
- 需要有盘子为空,即 f [ i ] [ j − 1 ] f[i][j-1] f[i][j−1]。
- 即问题转化为
#include<bits/stdc++.h>
using namespace std;
int f[15][15];
int main(){
int t;
int x,y;
cin>>t;
for(int i=1;i<=10;i++){
f[1][i]=1;
f[i][1]=1;
}
for(int j=2;j<=10;j++)
for(int k=2;k<=10;k++)
if(j<=k){
f[j][k]=f[j][j-1]+1;
}else{
f[j][k]=f[j-k][k]+f[j][k-1];
}
for(int i=1;i<=t;i++){
cin>>x>>y;
cout<<f[x][y]<<endl;
}
return 0;
}
【递归算法分析】
- 当盘子数量或者苹果数量为1时,方案数为1;
- 当苹果数<盘子数时,方案转化为f(x,x);
- 当苹果数=盘子数时,方案数为f(x,x-1)+1;
- 当苹果数>盘子数时,两种情况:(1)有空盘f(x,y-1), (2)无空盘f(x-y,y)。
#include<bits/stdc++.h>
using namespace std;
int f(int x,int y){
if(x==1||y==1)return 1;
if(x<y) return f(x,x);//苹果<盘子
if(x==y) return 1+f(x,y-1);//苹果==盘子
if(x>y) return f(x,y-1)+f(x-y,y);
}
int main(){
int t;
int x,y;
cin>>t;
for(int i=1;i<=t;i++){
cin>>x>>y;
cout<<f(x,y)<<endl;
}
return 0;
}