牛客网 balls (组合计数,打表,得到规律)
链接:https://ac.nowcoder.com/acm/contest/272/C
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
有一个盒子,里面有一个黑球和一个白球。每次随机取出盒子中的一个球,并将两个与取出球同色的球放进盒子(就是随机一种颜色将其个数+1)。
求n次取球后,盒子中白色球数目的期望。
输入描述:
输入一个整数n,表示取球次数。
输出描述:
输出一个实数,表示n次取球后白球数目的期望。答案保留7位小数。
示例1
输入
2
输出
2.0000000
说明
若第一次取出白球: 放入两个白球,则现在有一个黑球两个白球,概率为1/2。 若第二次取出白球,则现在有一个黑球三个白球,概率为1/2*2/3=1/3,期望个数为1/3*3=1; 若第二次取出黑球,则现在有两个黑球两个白球,概率为1/2*1/3=1/6,期望个数为1/6*2=1/3。 若第一次取出黑球: 放入两个黑球,则现在有两个黑球一个白球,概率为1/2。 若第二次取出黑球,则现在有三个黑球一个白球,概率为1/2*2/3=1/3,期望个数为1/3*1=1/3; 若第二次取出白球,则现在有两个黑球两个白球,概率为1/2*1/3=1/6,期望个数为1/6*2=1/3。 所以白球期望数目为2个。
备注:
0≤n≤106。
题意:题目意思很简单,每次从盒子里随机选取一种颜色的球,然后加1,经过n次操作后球白色球数目的期望。
题解:我先是按照普通方法找到解决方案,涉及排列组合计数,打表找出规律。
打表代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<queue>
#include<stack>
#define LL long long
#define INF 0x3f3f3f3f
#define PI 3.1415926535897932384
using namespace std;
const int mod=1e9+7;
int n;
double C(int n,int m)
{
if(m>n)
return 0;
if(m==0)
return 1;
double t=1;
int cnt=m;
for(int i=n;i>=n-m+1;i--)
{
t*=i*1.0/cnt;
cnt--;
}
return t;
}
double cal(int num)
{
double ans=1.0;
for(int i=n+1;i>=n+1-num+1;i--)
{
ans*=1.0*(n+2-i)/i;
}
return ans;
}
int main()
{
//cin>>n;
double ans=0;
for(int z=0;z<=20;z++)
{
n=z;
ans=0;
for(int i=1;i<=n+1;i++)
{
if(i<(n+1)/2)
ans+=1.0*i*(1.0/(n+2-i))*C(n,i-1)*cal(i-1);
else
{
ans+=1.0*i*(1.0/(i))*C(n,n-i+1)*cal(n-i+1);
}
}
printf("%.7lf\n",ans);
}
return 0;
}
最后得出一个式子 ans=0.5*(n+2);