HDU 5002(概率题目)

分析:

本题目要分开求每一个最大值为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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值