CSU - 2019 - Fleecing the Raffle(数学,组合数)

A tremendously exciting raffle is being held, with some tremendously exciting prizes being given out. All you have to do to have a chance of being a winner is to put a piece of paper with your name on it in the raffle box. The lucky winners of the p prizes are decided by drawing p names from the box. When a piece of paper with a name has been drawn it is not put back into the box – each person can win at most one prize. Naturally, it is against the raffle rules to put your name in the box more than once. However, it is only cheating if you are actually caught, and since not even the raffle organizers want to spend time checking all the names in the box, the only way you can get caught is if your name ends up being drawn for more than one of the prizes. This means that cheating and placing your name more than once can sometimes increase your chances of winning a prize. You know the number of names in the raffle box placed by other people, and the number of prizes that will be given out. By carefully choosing how many times to add your own name to the box, how large can you make your chances of winning a prize (i.e., the probability that your name is drawn exactly once)?

Input
There will be several test cases. Each case consists of a single line containing two integers n and p ( 2pn106 2 ≤ p ≤ n ≤ 10 6 ), where n is the number of names in the raffle box excluding yours, and p is the number of prizes that will be given away.

Output
Output a single line containing the maximum possible probability of winning a prize, accurate up to an absolute error of 10−6.

[题意]
就是说有一个抽奖活动,里面已经有很多牌了,然后游戏规则是你丢一张带你名字的牌进去,抽p张牌,只要你能抽出你的名字你就能获奖。但是这个抽奖活动有个BUG,就是你可以悄咪咪地丢好多带自己名字的牌进去,这样获奖的概率就会大一点,但是你只能抽出一张你的牌,不然就穿帮了。
所以,现在告诉你箱子里面有n张牌了,你可以丢无限次自己的名牌,你要抽p次。
现在问你,抽中一张且仅一张自己的名牌的最大概率。

[分析]

就是组合数啊,从自己名牌里抽一张,并且在其他牌里抽p-1张的情况数算出来,
再求出,所有情况数。两者相除就是答案了。

n和q都知道,所以我们遍历i,i表示自己名牌的数量。
所以公式就是(Ci取1)*(Cn取p-1)/(Cn+i取p)

然后就化简,
(Ci取1)就是等于i;
n和q确定,所以(Cn取p-1)就是一个常数,分母的部分还可以和(Cn+i取p)

化简就不赘述了,反正高中都学过了,因为我怕麻烦(逃

[代码]

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;


int main()
{
    double n, p;
    while (scanf("%lf%lf", &n, &p) != EOF)
    {
        double now = p / (1 + n);
        double ans = p / (1 + n);
        for (int i = 2; i <= 1000000; i++) {
            now *= i;
            now /= (i - 1);
            now /= (n + i);
            now *= (n + i - p);
            ans = max(now, ans);
        }
        printf("%.12f\n", ans);
    }
}

/*
i*c[n][p-1]/c[n+i][p];

1


*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值