放苹果

题目:把M个相同的苹果放到N个同样的盘子里,允许有盘子不放,问一共有多少种放法。

注(5,1,1)和(1,5,1)是同一种放法。

输入:

第一行是测试数据的数目t(0<=t<=20)。以下每行包含一个正整数,分别是M,N。用空格分开

输出:

对于每组数据,输出一个整数K

解析:

设函数f(i,k),i代表苹果的数量,k代表盘子的数量

1.当M<=N时,苹果的数量小于盘子的数量,苹果最多放到M个盘子里,所以f(M,N)=f(M,M)

2.当M>N时。假设有那么一个特殊的盘子,我的苹果要么放到所有盘子里,要么不放到那个盘子里。

所以一共的放法有f(M,N)=f(M,N-1)+f(M-N,N);

这样就可以通过递归不断缩小问题的规模,当函数调用一个函数时,下一个函数就会再考虑有没有这么一个盘子,放或者不放。

所以问题就会被分为有盘子为空和盘子不为空这两种情况。

最后只要考虑一下边界条件就好了,那就是当盘子的数量为1的时候只有一种放法。

这个问题当数据规模比较大的话,就会超时,要用动态规划来排除重复的解。

但是这里数据规模比较小,所以先用递归。


#include <iostream>
using namespace std;
int f(int i,int k);
int main(){
	int t,i,k;
	cin >> t;
	while(t--){
	
	cin >> i >> k;
	cout << f(i,k) << endl;
	
	}
	return 0;
}

int f(int i,int k){
	if(k == 1) return 1;
	if(i < k) return f(i,i);
	if(i > k) return f(i,k-1)+f(i-k,k);
	if(i == k) return f(i,k-1)+1; 
} 



“1206苹果”可能指的是一类经典的组合数学问题——将一定数量的苹果到若干个盘子的问题。以下以“把 \(m\) 个相同的苹果到 \(n\) 个相同的盘子允许有的盘子为空,问有多少种不同的法”为例进行分析。 ### 问题分析 设 \(f(m,n)\) 表示把 \(m\) 个苹果到 \(n\) 个盘子法数。可以分情况讨论: - 当 \(m = 0\) 时,即没有苹果,只有一种法,也就是所有盘子都为空,所以 \(f(0,n)=1\)。 - 当 \(n = 1\) 时,只有一个盘子,无论有多少个苹果,也只有一种法,即把所有苹果放在这一个盘子,所以 \(f(m,1)=1\)。 - 当 \(m < n\) 时,因为盘子数比苹果数多,多出来的盘子不会影响法的种类,所以 \(f(m,n)=f(m,m)\)。 - 当 \(m\geq n\) 时,又可以分为两种情况: - 至少有一个盘子为空,那么法数就等于把 \(m\) 个苹果到 \(n - 1\) 个盘子法数,即 \(f(m,n - 1)\)。 - 所有盘子都不为空,那么可以先在每个盘子一个苹果,此时还剩下 \(m - n\) 个苹果法数就等于把 \(m - n\) 个苹果到 \(n\) 个盘子法数,即 \(f(m - n,n)\)。所以 \(f(m,n)=f(m,n - 1)+f(m - n,n)\)。 ### 代码实现(Python) ```python def put_apples(m, n): if m == 0 or n == 1: return 1 if m < n: return put_apples(m, m) else: return put_apples(m, n - 1)+put_apples(m - n, n) # 示例,假设 12 个苹果到 6 个盘子 m = 12 n = 6 result = put_apples(m, n) print(f"把 {m} 个苹果到 {n} 个盘子法有 {result} 种。") ``` ### 复杂度分析 - **时间复杂度**:由于使用了递归的方法,时间复杂度较高,为指数级 \(O(2^{m + n})\)。 - **空间复杂度**:递归调用栈的深度为 \(O(m + n)\),所以空间复杂度为 \(O(m + n)\)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值