题意:有n个位置,两种竞选方式,一种是icpc,一种是acm,竞选n轮,每次决出一个位置,现在你要竞选,分别求出按icpc方式竞选的概率和按acm方式竞选的概率。icpc占两份,acm占一份。
析:很明显概率dp。若选择icpc方式,dp[i][j]表示到第i轮有j个人按第一种方式竞选成功。若选择acm方式,dp2[i][j]表示到第i轮有j个人竞选成功。
细节参见代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<map>
#include<vector>
#include<algorithm>
#include<cmath>
#include<queue>
#include<sstream>
#include<cstdlib>
using namespace std;
const int maxn=3000+5;
int n,a,b;
double dp[maxn][maxn],dp2[maxn][maxn],ans1,ans2;
int ua,ub,la,lb;
int main()
{
while(~scanf("%d%d%d",&n,&a,&b))
{
if(n>a+b)
{
printf("1.0000000000000000\n");
printf("1.0000000000000000\n");
continue;
}
ans1=0.0;ans2=0.0;
memset(dp,0,sizeof(dp));
memset(dp2,0,sizeof(dp2));
dp[0][0]=1.0;
dp2[0][0]=1.0;
for(int i=0;i<n;i++)
for(int j=0;j<=i&&j<=a;j++)
{
if(fabs(dp[i][j])<1e-8) continue;
ua=j;
ub=i-j;
la=a-ua;
lb=b-ub;
double fenmu=1.0/(la*2.0+lb+2.0);
ans1+=dp[i][j]*2.0*fenmu;
if(la>0) dp[i+1][j+1]+=dp[i][j]*la*2.0*fenmu;
if(lb>0) dp[i+1][j]+=dp[i][j]*lb*1.0*fenmu;
fenmu=1.0/(la*2.0+lb+1.0);
ans2+=dp2[i][j]*fenmu;
if(la>0) dp2[i+1][j+1]+=dp2[i][j]*la*2.0*fenmu;
if(lb>0) dp2[i+1][j]+=dp2[i][j]*lb*fenmu;
}
printf("%.12f\n",ans1);
printf("%.12f\n",ans2);
}
return 0;
}