#题解 放苹果

ε≡٩(๑>₃<)۶ 先来读题啊啊啊

题目背景

poj1664(poj1664)

题目描述

MM个同样的苹果放在NN个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分发5,1,11,1,5(5,1,1和1,1,5是同一种方法)

输入格式

第一行是测试数据的数目t0<=t<=20t(0 <= t <= 20),以下每行均包括二个整数M和N,以空格分开。1=MN=101<=M,N<=10

输出格式

对输入的每组数据MMNN,用一行输出相应的KK

输入输出样例

输入 #1

1
7 3

输出 #1

8

输入 #2

3
3 2
4 3
2 7

输出 #2

2
4
2

具体实现

这道题目要使用递归的思想,所谓递归,就是函数自己调用自己,并把问题的规模不断缩小。
别急,一步步教你!我们先假设有一个函数可以完成这道题,命名为rank,有apple和plate两个参数,分别表示有apple个苹果和plate个盘子。那改有哪些代码呢?别急先看看样例。

  1. 7和3,苹果数大于盘子数,此时就有两种情况,第一种是不存在空盘子,也就是每个盘子里先放上一个,就变为了苹果数减盘子数个苹果放到原来的盘子里,再加上第二种,存在空盘子,也就是原来的苹果放到盘子数减一个盘子里,然后一直循环就可以了。
  2. 再看2和7,盘子数大于苹果数,也就必定有空盘子,相当于把apple个苹果放到apple个盘子里,依次循环。
    先把这些补上(づ。◕ᴗᴗ◕。)づ
if(apple>=plate){
	// 1.用上所有盘子  2. 存在空盘子
	return rank(apple-plate,plate) + rank(apple,plate-1);
}else{
	return rank(apple,apple);
}

但是只有这些是不够的,这样函数就会陷入死循环(`へ´),但如果加上中止条件,就不会发生这种事,那有什么中止条件呢?

  1. 当苹果没有了或只有一个时,只有一种放法,返回1.
  2. 当盘子只有一个时,只有一种放法,也返回1.
  3. 当没有盘子时,放不了,返回0.
    把这些写在函数的开头( • ̀ω•́ )✧
if(apple == 1||apple==0) return 1;
if(plate==1)return 1;
if(plate==0) return 0; 

这只是准备工作咳咳,函数写完了❥(ゝω・✿ฺ)
函数代码:

int rank(int apple,int plate){
	if(apple == 1||apple==0) return 1;
	if(plate==1)return 1;
	if(plate==0) return 0; 
	
	
	if(apple>=plate){
		// 1.用上所有盘子  2. 存在空盘子
		return rank(apple-plate,plate) + rank(apple,plate-1);
	}else{
		return rank(apple,apple);
	}
	
}

接下来就是主函数啦

定义变量nn,数组apa,p,分别是nn次判断,苹果和盘子的数量。
接下来forfor循环输入,forfor循环调用并输出。
代码ㄟ(≧◇≦)ㄏ

int main(int argc, char** argv) {
	int n,a[20],p[20];
	cin >> n;
	for(int i = 0; i < n; i++){
		cin>>a[i]>>p[i];
	}
	for(int i = 0; i < n; i++){
		cout<<rank(a[i],p[i])<<endl;
	}
	return 0;
}

完整代码

请勿抄袭o(`ω´*)o

#include<bits/stdc++.h>//万能头文件 

using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int rank(int apple,int plate){
	if(apple == 1||apple==0) return 1;
	if(plate==1)return 1;
	if(plate==0) return 0; 
	
	
	if(apple>=plate){
		// 1.用上所有盘子  2. 存在空盘子
		return rank(apple-plate,plate) + rank(apple,plate-1);
	}else{
		return rank(apple,apple);
	}
	
}

int main(int argc, char** argv) {
	int n,a[20],p[20];
	cin >> n;
	for(int i = 0; i < n; i++){
		cin>>a[i]>>p[i];
	}
	for(int i = 0; i < n; i++){
		cout<<rank(a[i],p[i])<<endl;
	}
	return 0;
}


\color{red}各位神犇可以尝试一下数的划分
写完别忘来看题解呦~