题意:n个球,取出p+q个球,其中黑球p个,白球q个,求一个黑球的取值区间,使得黑球数在该区间概率最低值为p
解析:
设n个球中有k个黑球的事件为Ak ,设取出p+q个球中有p个黑球为事件B题目所有概率为sum{p(Ak|B)}>=pri的k的取值区间
p(Ak|B)不好求解,通过贝叶斯公式p(Ak|B) = p(B|Ak)*p(Ak)/p(B)其中
p(B|Ak) = C(p, k) * C(q, n-k) / C(p+q, n);
p(B) = sum( p(B|Ak) * p(Ak) ) k = 0...n;
由于有多少个黑球是等概率的,因此p(Ak)可以提出来约掉
p(Ak|B) = p(B|Ak) / sum( p(B|Ak) );
p(Ak|B) = (C(p, k) * C(q, n-k)) / sum( (C(p, t) * C(q, n-t)) ) 其中t的取值
为枚举的区间[0, n]
上式能够用来求出某个k值的概率值,由于需要枚举一个区间,那么将
这个区间的所有概率相加即可
#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <numeric>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
using namespace std;
#define PI acos(-1.0)
typedef long long LL;
const double EPS=1e-12;
LL c[55][55],temp;
int n,p,q,pri;
void inint()
{
memset(c,0,sizeof(c));
c[0][0]=1;
int i,j;
for(i=1;i<55;i++)
{
c[i][0]=1;
for(j=1;j<=i;j++)
c[i][j]=c[i-1][j-1]+c[i-1][j];
}
}
int sign(double x)
{
return x < -EPS ? -1 : x > EPS;
}
void solve()
{
int i,j,k;
temp=0;
LL res;
for(j=p;j+q<=n;j++)
temp+=c[j][p]*c[n-j][q];
int left=0,right=0,len=100;
for(i=0;i<=n;i++) //因为p可以为0,所以必须全部搜一遍
{
for(j=i;j<=n;j++)
{
res=0;
if(j-i+1>=len) continue;
for(k=i;k<=j;k++)
{
res+=c[k][p]*c[n-k][q];
}
if( sign(res*100.0/temp-pri)>=0 )
{
left=i;
right=j;
len=j-i+1;
}
}
}
printf("%d %d\n",left,right);
}
int main()
{
inint();
while(~scanf("%d%d%d%d",&n,&p,&q,&pri))
{
solve();
}
return 0;
}