【Test 2016-10-2】chance {概率dp}

5 篇文章 0 订阅
1 篇文章 0 订阅
  • 【题目描述】
    pluto 去找妹子约会,然而要求和pluto 玩一个游戏,pluto 赢了才能获得约会的机会。游戏内容为:现在有N 个袋子(你可以认为它是哆啦A 梦的口袋,每个袋子里放着一些球),所以容量十分大,第i 个袋子里放着编号为Li 到Ri 的球(除编号外完全相同),pluto 需要从每个袋子里摸出一个球,第i 个袋子里任何一个球被摸到的概率是1/(Ri-Li + 1),如果pluto 摸出的球中有K% 或以上的球的编号的第一位是1(比如11,121,199 的第一位是1, 而21,233 第一位就不是1),那么pluto 就将赢得与约会的机会。现在pluto 想知道他能人生中第一次与妹子约会的概率有多大。

  • 【Sample Input】(第一行两个整数N,K;接下来N 行,每行两个整数,Li 和Ri)
    2 50
    1 2
    9 11

  • 【Sample Output】(一行一个实数(保留7 位小数)表示答案绝对误差不超过10^-6)
    0.8333333

  • 【数据范围】
    对于100% 的数据,0 <= k<=100,0 < Li<=Ri
    对于30% 的数据,n<=10,Li<=Ri<=100
    对于60% 的数据,n<=500,Li<=Ri<=2000
    对于100% 的数据,n<=2000,Li<=Ri<=10^18


  • 【题解】
    首先我们显然要先算出pluto从每个袋子里摸出第一位为1的球的概率{暴力随便做};
    设从第 i 个袋子里摸出满足要求的球的概率为p[i]:
    {状态} f [ i ] [ j ]:前i个袋子里取出 j 个第一位为1的球的概率
    {方程} f [ i ] [ j ] = f [ i ] [ j ] = f [ i - 1 ] [ j ] * ( 1 - p [ i ] ) + f [ i - 1 ] [ j - 1 ] * p [ i ] ; //分为i-1个已取j个和取j-1个考虑
    最后将取出球大于等于k%的状态累加即为答案。

#include <cstdio>
#include <iostream>
#define LL long long
LL n,k,num[2005],l[2005],r[2005];
double f[2005][2005],p[2005],ans;
int main()
{
    scanf("%lld%lld\n",&n,&k);
    for (int i=1;i<=n;++i) scanf("%lld%lld\n",&l[i],&r[i]);
    for (int i=1;i<=n;++i)
    {
        LL t=1;
        for (int j=0;j<=18 && t<=r[i];++j,t*=10)
            if (l[i]<=t)
            {
                if (r[i]>=t+t-1) num[i]+=t;
                else num[i]+=r[i]-t+1;
            }
            else if (l[i]<t+t) num[i]+=std::min(t+t,r[i]+1)-l[i];
    }
    for (int i=1;i<=n;++i) p[i]=1.0*num[i]/(r[i]-l[i]+1);
    f[1][0]=1-p[1];f[1][1]=p[1];
    for (int i=2;i<=n;++i)
        for (int j=0;j<=i;++j)
            f[i][j]=f[i-1][j]*(1-p[i])+f[i-1][j-1]*p[i];    
    int m=(n*k+99)/100;
    for (int i=m;i<=n;++i) ans+=f[n][i];
    printf("%.7f",ans);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值