排队购票 典型递归 java

本文探讨了一种典型的组合计数问题——如何计算不同的人群排队购票的方案总数,以确保售票处不会出现找不开钱的情况。通过递归方法,文章详细解析了递推公式,并给出了具体的Java实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 问题提出

一场球赛开始前,售票工作正在紧张的进行中。每张球票为50元,现有30个人排队等待购票,其中有20个人手持50元的钞票,另外10个人手持100元的钞票。假设开始售票时售票处没有零钱,求出这30个人排队购票,使售
票处不至出现找不开钱的局面的不同排队种数。(约定:拿同样面值钞票的人对换位置后为同一种排队。)

2.递归设计要点

我们考虑一般情形:有m+n个人排队等待购票,其中有m 个人手持50元的钞票,另外n个人手持100元的钞票。求出这m+n个人排队购票,使售票处不至出现找不开钱的局面的不同排队种数(这里正整数m,n从键盘输入)。

这是一道典型的组合计数问题,考虑用递推求解。

令f(m,n)表示有m个人手持50元的钞票,n个人手持100元的钞票时共有的方案总数。我们分情况来讨论这个问题。

(1) n=0

n=0意味着排队购票的所有人手中拿的都是50元的钱币,注意到拿同样面值钞票的人对换位置后为同一种排队,那么这m个人的排队总数为1,即f(m,0)=1。

(2)m<n

当m<n时,即排队购票的人中持50元的人数小于持100元的钞票,即使把m张50元的钞票都找出去,仍会出现找不开钱的局面,所以这时排队总数为0,即f(m,n)=0。

 (3)其它情况

我们思考m+n个人排队购票,第m+n个人站在第m+n-1个人的后面,则第m+n个人的排队方式可由下列两种情况获得:

1)  第m+n个人手持100元的钞票,则在他之前的m+n-1个人中有m个人手持50元的钞票,有n-1个人手持100元的钞票,此种情况共有f(m,n-1)。

2)  第m+n个人手持50元的钞票,则在他之前的m+n-1个人中有m-1个人手持50元的钞票,有n个人手持100元的钞票,此种情况共有f(m-1,n)。

由加法原理得到f(m,n)的递推关系:

f(m,n)=f(m,n-1)+f(m-1,n)

初始条件:

当m<n时,f(m,n)=0

当n=0时,f(m,n)=1

package basic_practice;

import java.util.Scanner;

public class anlian_bfs {

	
	static long f(int m,int n){
		long y ;
		if(n==0)y=1;
		else if(m<n)y=0;           //确定初始条件
		else y=f(m-1,n)+f(m,n-1);    //实施递归
		return y;
		
	}
	public static void main(String[] args) {
		int m,n;
		Scanner in=new Scanner(System.in);
		m=in.nextInt();
		n=in.nextInt();
		System.out.println(f(m,n));
	}
	 
}


排队购票的问题可以看作是一个典型递归场景。假设有一排人正在购买电影票,每个人需要买一定数量的票,并且售票窗口每次只能处理一个人的需求。我们可以通过递归来模拟这个过程。 下面通过一个简单的例子来展示如何用C++实现基于递归排队购票算法: ### 示例情景 假设有 `n` 个人排队购票,每人需求一张到若干张不等的票数。每轮循环只允许当前第一个人完成其购票操作后再进入下一轮次序调整直到所有人买到所需门票为止。 ```cpp #include <iostream> using namespace std; void buyTicket(int *ticketsNeeded, int n, int index) { if (index >= n || ticketsNeeded[index] == 0){ return; } // 当前位置的人购买了一张票 cout << "Person at position " << index+1 << " buys a ticket." << endl; ticketsNeeded[index]--; // 如果此人还需要更多票,则继续让他买 if(ticketsNeeded[index] > 0 ){ buyTicket(ticketsNeeded, n, index); } else{ // 否则移动至下一个顾客 buyTicket(ticketsNeeded, n, index + 1); } } int main(){ int numPeople = 4; // 假设共有4名顾客 // 每位顾客所需要的票的数量初始化数组 {5, 2, 3, 4} int tickets[] = {5, 2, 3, 4}; // 开始从第一个客户开始购票流程 buyTicket(tickets, numPeople, 0); return 0; } ``` #### 解释上述代码的工作原理: 1. **函数定义** - 我们定义了一个名为 `buyTicket()` 的递归函数,它接受三个参数分别是每个人的需求数组、人数以及当前位置索引。 2. **基本条件判断** - 若到达最后一位或该人的所有需求已满足就停止递归。 3. **单步执行及递归调用** - 首先打印出哪位用户正在进行购票动作; - 然后将对应元素减一表示此次成功购得一张票的情况发生改变后的状态更新回去再做检查是否仍需额外数量以决定接下来步骤应该重复自身还是转向后续成员的操作之上。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值