upc 3025 Fleecing the Raffle

抽奖算法优化
本文探讨了一个抽奖算法的问题,通过数学公式推导,解决了在有限条件下如何最大化个人中奖概率的策略。文章提供了一种通过调整投入抽奖次数来优化获奖概率的方法。

Fleecing the Raffle

时间限制: 2 Sec  内存限制: 64 MB  Special Judge
提交: 179  解决: 49
[提交] [状态] [讨论版] [命题人:外部导入]
题目描述
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)?

 

输入
The input consists of a single line containing two integers n and p (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 a single line containing the maximum possible probability of winning a prize, accurate up to an absolute error of 10 -6 .

 

样例输入
3 2

 

样例输出
0.6

 

提示

样例输入2
23 5
样例输出2
0.45049857550

题意

除了你的其他N个人各写一张带名字纸条放进抽奖箱里,共有P个奖,你可以写任意X张纸条放进抽奖箱里,你不能获奖两次,求X的最优解使得获奖概率最大。

分析

概率问题,数学推公式,但是求组合数过程会爆精度,所以要把式子化简一下。

 

///  author:Kissheart  ///
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<vector>
#include<stdlib.h>
#include<math.h>
#include<queue>
#include<deque>
#include<ctype.h>
#include<map>
#include<set>
#include<stack>
#include<string>
#define INF 0x3f3f3f3f
#define FAST_IO ios::sync_with_stdio(false)
const double PI = acos(-1.0);
const double eps = 1e-6;
const int MAX=1e6+10;
const int mod=1e9+7;
typedef long long ll;
using namespace std;
#define gcd(a,b) __gcd(a,b)
inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
inline ll qpow(ll a,ll b){ll r=1,t=a; while(b){if(b&1)r=(r*t)%mod;b>>=1;t=(t*t)%mod;}return r;}
inline ll inv1(ll b){return qpow(b,mod-2);}
inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll r=exgcd(b,a%b,y,x);y-=(a/b)*x;return r;}
inline ll read(){ll x=0,f=1;char c=getchar();for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;for(;isdigit(c);c=getchar()) x=x*10+c-'0';return x*f;}
//freopen( "in.txt" , "r" , stdin );
//freopen( "data.txt" , "w" , stdout );
int main()
{
    int n,p;
    int x;
    scanf("%d%d",&n,&p);
    if(n==1)
    {
        printf("0.5\n");
        return 0;
    }
    x=n/(p-1);

    double ans=1.0*x*p/(x+n-p+1);
    for(int i=0;i<=p-2;i++)
    {
        ans=ans*(n-i);
        ans=ans/(x+n-i);
    }

    printf("%.11lf\n",ans);
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/Kissheart/p/9748382.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值