找钱问题

本文探讨了一个购票场景下的递归解决方案,假设公园票价为5角,游客持有5角和1元两种货币,售票员起初无零钱可找。通过递归方法,解决了在不同数量的5角和1元货币持有者情况下,如何安排购票顺序才能顺利完成购票的问题。
公园票价为5角。假设每位游客只持有两种币值的货币:5角、1元。
再假设持有5角的有m人,持有1元的有n人。
由于特殊情况,开始的时候,售票员没有零钱可找。
我们想知道这m+n名游客以什么样的顺序购票则可以顺利完成购票过程。

显然,m < n的时候,无论如何都不能完


分析:从题目给出的代码就可以看出,这是一个递归,出口已经给出来了。如果一开始是m个5毛,n个一块,可以看到这并不容易找到,那我们就利用一下递归,如果f(m,n)不好求的话,我们可以先看f(m-1,n)和f(m,n-1)的情况,也就是分别去掉一个拿5毛的和一个拿1块的,然后再将这两种情况相加,最后如果m<n,说明无解,则返回0如果n==0,那一定只有一种情况,因为所有人都拿5毛了,如果拿5毛的比拿1块的还要多或者相等,那可以继续递归下去,这样将所有的情况相加,就可以得到所有的可能了,其实这是一个模拟人来等车的过程,假如一开始一个人都没有,那么,每过一个时刻,我们让一个人来排队,这个人可能拿5毛,可能拿一块,最后总共来了m+n个人,而所有的情况相加,就可以得到答案,可以看出,递归实际上是从结果到开始状态,也就是倒着递推,来找到所有的情况的。 

#include<iostream>
using namespace std;
//n,表示1元钱币数量
//m表示5角钱币数
int f(int n,int m)
{
	if(m<n) return 0;
	if(m==1)	return 1;
	if(n==0) 	return 1;
	return f(n-1,m)+f(n,m-1);
 } 
int main()
{
	int n,m;
	cin>>n>>m;
	cout<<f(n,m);
	return 0;
 } 

硬币找钱问题旨在使用最少的硬币个数来完成交易,交易包括付款和找钱两个过程。设有6种不同面值的硬币,各硬币的面值分别为5分,1角,2角,5角,1元,2元。购物时可以使用的各种面值的硬币个数存于数组中,商店里各面值的硬币有足够多[^2]。 #### 问题分析 该问题的目标是在给定各种面值的硬币个数和付款金额的情况下,计算使用硬币个数最少的交易方案。例如,一次购物需要付款0.55元,不同的付款和找钱组合会使用不同数量的硬币,需要找出使用硬币个数最少的方案[^2]。 #### 贪心算法实现及问题 贪心算法的基本思想是每次都选择面值最大的硬币,直到凑够所需金额。以下是一个使用贪心算法解决硬币找钱问题的示例代码: ```cpp #include "iostream" #include "fstream" #include <cstring> using namespace std; /* 最大面值优先 */ int coins[6]; int greedy(double money) { cout << "找钱时用到的钱币有:"; int m[] = {200, 100, 50, 20, 10, 5}; // 硬币面值,单位为分 money = (int)(money * 100); // 将元换为分 int i, j; int count = 0; for(i = 0; i < 6; i++) // 硬币种数 for(j = 1; j <= coins[i]; j++) // 每种硬币的数量 if(money >= m[i]) { money -= m[i]; cout << " " << m[i]; count++; if(money == 0) return count; } return -1; } int main() { ifstream fin("硬币找钱.txt"); int i; double money; while(!fin.eof()) { memset(coins, 0, sizeof(coins)); cout << " 5\t10\t20\t50\t100\t200\n"; cout << "输入各种面值的硬币个数:"; for(i = 0; i < 6; i++) { fin >> coins[5 - i]; cout << coins[5 - i] << "\t"; } cout << "\n输入要找的钱数:"; fin >> money; cout << money * 100 << endl; cout << "\n最少的硬币数为:" << greedy(money); cout << endl; } fin.close(); return 0; } ``` 然而,贪心算法并不一定能得到最优解。贪心算法只考虑当前步骤的最优选择,而不考虑整体的最优性。在某些情况下,贪心算法可能会错过使用更少硬币的方案。 #### 动态规划解决思路 动态规划算法可以解决贪心算法无法得到最优解的问题。动态规划的基本思想是将问题分解为子问题,并保存子问题的解,避免重复计算。对于硬币找钱问题,可以通过定义状态和状态转移方程来求解。 #### 复杂度分析 - **时间复杂度**:贪心算法的时间复杂度为$O(n)$,其中$n$是硬币的种类数。动态规划算法的时间复杂度通常为$O(m * n)$,其中$m$是要找的钱数,$n$是硬币的种类数。 - **空间复杂度**:贪心算法的空间复杂度为$O(1)$,只需要常数级的额外空间。动态规划算法的空间复杂度通常为$O(m)$,需要一个数组来保存子问题的解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值