zoukankan      html  css  js  c++  java
  • 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]);
        }
    }
    

      

  • 相关阅读:
    oracle的安装与plsql的环境配置
    Working with MSDTC
    soapui-java.lang.Exception Failed to load url
    Oracle 一个owner访问另一个owner的table,不加owner
    Call API relation to TLS 1.2
    Call API HTTP header Authorization: Basic
    VS2008 .csproj cannot be opened.The project type is not supported by this installat
    The changes couldn't be completed.Please reboot your computer and try again.
    Create DB Table View Procedure
    DB Change
  • 原文地址:https://www.cnblogs.com/intwentieth/p/9688611.html
Copyright © 2011-2022 走看看