CF26D Tickets

本文探讨了一个足球票售卖场景中的概率问题,通过分析票价与顾客支付方式的关系,将其转化为一个经典的卡特兰数问题。文章详细介绍了如何使用卡特兰数及其变形来计算能够顺利完成交易的概率。

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

传送门

题目大意

卖足球赛的票,票价是 10/,你手中有 k k k 张 10 元钱,并且知道有 n n n 个人来买票时会带 10 元, m m m 个人会带 20 元钱。你可以顺利卖票,即每次都能找得出钱的概率是多少。

Solution

首先分析顺利卖票,由于票价是 10 元,所以带 10 元的人是不需要你找钱,相反,他们来买票还可以为你提供找 20 元的钱。所以,得出结论,10 元是好的,20 元是不好的。

我们可以先算有多少合法的序列,然后除以总方案即可。

于是,我们开始转化模型。

step 1

由上面的结论可以轻易推出,如果一种买票的顺序,使得某一次,之前带 20 元来买票的人比带 10 元的人加上原有的 k k k 张 10 元还要多了,那么就找不开钱,也就是没有顺利卖票了。

这很容易联想到栈,进一步的,就是典型的卡特兰数的变形。

问题就是,栈中原有 k k k 个元素,现在有 n n n 次入栈操作, m m m 次出栈操作,问有多少种操作顺序。

step 2

显然,这样仍不足以解决这个问题,因为毕竟不是卡特兰数的模板。我们回顾一下卡特兰数的推导:

在一个坐标系中,从原点出发,可以向上走 m m m 步,向右走 n n n 步,请问有多少种方式,可以不越过直线 y = x y=x y=x 并且到达点 ( n , m ) (n,m) (n,m)

在这题中,可以把初始的 k k k 个元素转化为:在坐标轴上,从坐标 ( k , 0 ) (k,0) (k,0) 出发。

所以题目又转化为:
在一个直角坐标系中,从点 (0,k) 出发,可以向上 m 或向右 n 步,且必须在直线 y=x 的下方(包括边界),求有多少种合法的非降路径。

step 3

最后,为了解决上面的问题,我们仍然从卡特兰数的推导中获得启发。即利用 P ( A ) = 1 − P ( A ‾ ) P(A)=1-P(\overline{A}) P(A)=1P(A)

直接算不合法的概率,当然首要还是先算不合法的方案数。

显然,可以先得出总方案数是 C n + m n C_{n+m}^n Cn+mn,其中不合法的方案,反映在坐标轴上一定是经过直线 y = x + 1 y=x+1 y=x+1 的,由卡特兰数的路径计数推导,可以得出,我们只要将起点关于直线 y = x + 1 y=x+1 y=x+1 对称,即将起点变成 ( − 1 , k + 1 ) (-1,k+1) (1,k+1),然后可以得出,不合法的方案数是 C n + m k + n + 1 C_{n+m}^{k+n+1} Cn+mk+n+1。因此不合法的概率就是:
C n + m k + n + 1 C n + m n \frac{C_{n+m}^{k+n+1}}{C_{n+m}^n} Cn+mnCn+mk+n+1

因此合法的概率就是:
1 − C n + m k + n + 1 C n + m n 1-\frac{C_{n+m}^{k+n+1}}{C_{n+m}^n} 1Cn+mnCn+mk+n+1
= 1 − ( n + m ) ! ( m − k − 1 ) ! ( k + n + 1 ) ! ( n + m ) ! n ! m ! =1-\frac{\frac{(n+m)!}{(m-k-1)!(k+n+1)!}}{\frac{(n+m)!}{n!m!}} =1n!m!(n+m)!(mk1)!(k+n+1)!(n+m)!
= 1 − n ! m ! ( m − k − 1 ) ! ( k + n + 1 ) ! =1-\frac{n!m!}{(m-k-1)!(k+n+1)!} =1(mk1)!(k+n+1)!n!m!

所以最后的代码就是个式子,很短。

Code

#include<bits/stdc++.h>
#define ll long long
#define inf 1<<30
#define INF 1ll<<60
#define pb push_back
using namespace std;
int main()
{
	int n,m,k;
	scanf("%d%d%d",&n,&m,&k);
	if(n+k<m){puts("0");return 0;}//先判无解
	int up=m,down=k+n+1;
	double ans=1;
	for(int i=0;i<=k;i++,up--,down--)
		ans=ans*1.0*up/down;
	printf("%.5lf\n",1-ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值