分析:
本题目要分开求每一个最大值为x的概率,要求这一个可以先求小于等于x的概率,然后用p[x]-p[x-1]计算得出,最大值为x的概率。
假定当前最大值为x。
那么定义f[ i ]为还有i轮结束,是的最大值不超过x的概率。 p1(出现蓝色的概率) , p2(出现白色的概率)
显然对于f[ i ] 有x种可行性转移,f[i] = sum(f[i-k]*pow(p1,k-1)*p2),(1<=k<=x),可以循环递推维护sum就可以了。
但是要注意对于i<x的还有一种可行性转移: f[ i ] += pow(p1,i);因为可以这i个全部为蓝球+1代表最后剩余在桌子上的球不超过x个。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
#define rep(i,n) for(int (i)=0;(i)<(n);(i)++)
#define rep1(i,x,n) for(int (i)=x;(i)<=(n);(i)++)
const int N = 2000;
long double pow_[N],ans[N],f[N],p1,p2;
int n,a,b;
long double find(int x){
f[0]=1;
double sum=p2;
for(int i=1;i<=n;i++){
if(i-x-1>=0) sum=sum-p2*pow_[x]*f[i-x-1];
f[i]=sum;
if(i<x) f[i]+=pow_[i];
sum=sum*p1+f[i]*p2;
}
return f[n];
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%d %d %d",&n,&a,&b);
p1=1.0*b/a,p2=1.0-1.0*(b)/a;
pow_[0] = 1;
rep1(i,1,N-1) pow_[i]=pow_[i-1]*p1;
rep1(i,1,n+1) ans[i]=find(i);
ans[0]=0;
for(int i=n+1;i>=1;i--)
ans[i]=ans[i]-ans[i-1];
long double res=0;
for(int i=1;i<=n+1;i++) res=res+ans[i]*i;
double tem = res;
printf("%.3lf\n",tem);
}
return 0;
}