第一场-F-Fleecing the Raffle

题目链接:点击打开链接

(一)题面:

Description

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≤106 ), 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.

Sample Input

3 2
23 5

Sample Output

0.6
0.45049857550

(二)题目大意:

现在一个抽奖箱里面有n张不同的卡片,需要从中抽取p张。现在你想在抽奖箱中加入k张卡片(代表你),你需要确定一个k,使得抽到你且仅抽到你一次的概率最大。并输出该最大概率。


(三)解题思路:

  1. 数学题,写表达式,求最值即可。
  2. 不难得到加入k张卡片后,所求概率为:
    P(k)=C(k,1)*C(n,p-1)/C(n+k,p)
    =k*C(n,p-1)/C(n+k,p)
    =k*[n!/((p-1)!*(n-p+1)!)]*[(p!)*(n+k-p)!/(n+k)!]
    =k*p*n!*(n+k-p)!/((n-p+1)!*(n+k)!);
  3. P(k+1)/P(k)=(k+1)*(n+k-p+1)/((n+k+1)*k),令P(k+1)/P(k)>1,得:k<(n-p+1)/(p-1),故使概率最大时,K=floor((n-p+1)/(p-1))+1;

(四)具体代码:
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#define LL long long
using namespace std;
double get(double x,double y,int k){
    double res=1.0;
    for(int i=0;i<=k-2;i++){
        res=res*(x-i)/(y-i);
    }
    res/=y-k+1;
    return res;
}
int main(){
    freopen("in.txt","r",stdin);
    LL n,p;
    while(cin>>n>>p){
        int k=(n-p+1)/(p-1);
        double ans=p*1.0*(k+1)*get(n,n+k+1,p);
        printf("%.10lf\n",ans);
    }
    return 0;
}


(五)总结:
  1. 实际写的时候,没有想到求最值点,但是猜得到应该存在最值点,所以当时直接从1开始遍历,直到概率值变小就退出,本以为会T的,结果最后跑得还挺快的。估计数据不卡吧。
  2. 数学题目需要多推敲。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值