• HDU5985 Lucky Coins 概率dp


    题意:给你N种硬币,每种硬币有Si个,有Pi 概率朝上,每次抛所有硬币抛起,所有反面的拿掉,问每种硬币成为最后的lucky硬币的概率。

    题解:都知道是概率dp,但是模拟赛时思路非常模糊,很纠结,dp[10][1e6]这个状态让我觉得丝毫没有用,当时一直以为每种硬币是互相独立的。然后中间吃了个饭,回来又想了很久很久,就是不想看题解,然后发现,这个dp和极限有关,同时状态跟走了几步有极大的关系。否则你初始值根本没法赋,那么显然我猜既然保留6位,肯定当数字小到一定程度时是可以忽略的,也就是进行的次数多了后。随意打了个表,0.6的36次小于1e-8,然而事实是这样还不够。好像要开到70多。然后就定义一个dp1[i][j]=(1-pij )^num[i]为进行了j轮后第i种硬币全无的概率(表示不看题解这个式子怎么算都不知道),那么1-dp1[i][j]就是还活着的概率。那么这个问题也就变成了第j轮后网上很多题解的那个式子

    ans[i]=∑1~max (dp2[i][j]-dp2[i][j+1])*∏k!=i  dp1[k][j]   我没考虑到的主要是要减掉 dp2[i][j+1],因为这里相当于是在第j这个位置就要结束游戏,所以要剪掉下一步还存活的概率。稍微还是有点不理解,概率题好难想啊。

    #include<cstdio>
    #include<iostream>
    #include<bitset>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<set>
    #include<cmath>
    #define mp make_pair
    #define pb push_back
    #define ll long long
    #define lc no[x].ch[0]
    #define rc no[x].ch[1]
    #define pa no[x].fa
    #define db double
    #define ls x<<1
    #define rs x<<1|1
    #define For(i,a,b) for(int i=a;i<=b;i++)
    #define Forr(i,a,b) for(int i=a;i>=b;i--)
    using namespace std;
    const int maxn=80;
    
    int num[20];
    double num1[20];
    double dp1[20][100];
    double dp2[20][100];
    double ans[20];
    int n;
    double q_pow(db vs,int t)
    {
        double res=1.0;
        while(t)
        {
            if(t&1)
            {
                res*=vs;
            }
            vs=vs*vs;
            t>>=1;
        }
        return res;
    }
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
            {
                scanf("%d%lf",&num[i],&num1[i]);
            }
            for(int i=1;i<=n;i++)
            {
                ans[i]=0.0;
            }
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<maxn;j++)
                {
                    double st=q_pow(num1[i],j);
                   // cout<<st<<endl;
                    dp1[i][j]=q_pow(1-st,num[i]);
                    dp2[i][j]=1-dp1[i][j];
                }
            }
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<maxn;j++)
                {
                    double tmp=1.0;
                    for(int k=1;k<=n;k++)
                    {
                        if(k!=i)tmp*=dp1[k][j];
                    }
                    ans[i]+=(dp2[i][j]-dp2[i][j+1])*tmp;
                }
            }
            if(n==1){printf("%.6f
    ",1.0);continue;}
            for(int i=1;i<n;i++)
            {
                printf("%.6f ",ans[i]);
            }printf("%.6f
    ",ans[n]);
        }
    }
    

      

  • 相关阅读:
    spring3.0注解定时任务配置及说明
    程序员,吃什么个对身体好
    log4j 实例 , 浅析
    使用dom4j创建和解析xml
    Java XML解析工具 dom4j介绍及使用实例
    网络原理分析
    Python教程-使用Python解释器
    Jenkins中使用jmeter的脚本
    jmeter: line 129: [: : integer expression expected jmeter: line 200: /usr/bin/java/bin/java: Not a directory解决办法
    阿里云centos安装Jenkins
  • 原文地址:https://www.cnblogs.com/intwentieth/p/9688611.html
Copyright © 2020-2023  润新知