1. 程式人生 > >CSU-2019 Fleecing the Raffle

CSU-2019 Fleecing the Raffle

line draw ror 最大 http 個人 aced Once sts

CSU-2019 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 ( 2≤p≤n≤1062≤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

題解

題意:抽獎活動,可以放入任意張有自己名字的紙片參與抽獎,當且僅當帶有自己名字的紙片被抽取兩次時會被抓住,視作失敗。共抽取p件獎品,參與抽獎的有n個人,問自己最大獲獎概率是多少

設x為放入的自己名字的紙片個數,則放入x張獲獎概率為
\[ \frac{C_x^1Cn^{p-1}}{C_{n+x}^p}=\frac{x\times p}{n+1}\prod_{i=2}^x\frac{n-p+i}{n+i} \]
當從x-1到x,概率乘以\(\frac{x}{x - 1}\times\frac{n-p+x}{n+x}\)

,遞推求概率,當概率開始變小時終止循環,輸出答案

#include<bits/stdc++.h>
using namespace std;
int main() {
    int n, p;
    while (scanf("%d%d", &n, &p) != EOF) {
        double now = (double)p / (double)(n + 1.0);
        double ans = 0.0;
        int x = 2;
        while (1) {
            if (ans > now) break;
            else ans = now;
            now *= (double)x / (double)(x - 1.0) * (double)(n + x - p) / (double)(n + x);
            x++;
        }
        printf("%.11lf", ans);
    }
}
/**********************************************************************
    Problem: 2019
    User: Artoriax
    Language: C++
    Result: AC
    Time:28 ms
    Memory:2024 kb
**********************************************************************/

CSU-2019 Fleecing the Raffle