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\n",1.0);continue;}
        for(int i=1;i<n;i++)
        {
            printf("%.6f ",ans[i]);
        }printf("%.6f\n",ans[n]);
    }
}

原文地址:https://www.cnblogs.com/intwentieth/p/9688611.html

时间: 2024-11-02 22:05:59

HDU5985 Lucky Coins 概率dp的相关文章

atcoderI - Coins ( 概率DP)

I - Coins Time Limit: 2 sec / Memory Limit: 1024 MB Score : 100100 points Problem Statement Let NN be a positive odd number. There are NN coins, numbered 1,2,…,N1,2,…,N. For each ii (1≤i≤N1≤i≤N), when Coin ii is tossed, it comes up heads with probabi

2017 ICPC Asia Urumqi A.coins (概率DP + 期望)

题目链接:Coins Description Alice and Bob are playing a simple game. They line up a row of nn identical coins, all with the heads facing down onto the table and the tails upward. For exactly mm times they select any kk of the coins and toss them into the

2017 ICPC乌鲁木齐 A Coins 概率dp

Coins 题意:一开始所有n个硬币都是反面朝上的,每次必须拿k个来抛,抛的人足够聪明,问m次之后向上的硬币的期望. 首先说了这个足够聪明的意思,就是只要向反面的有k个就不会sb地去拿向正面的来抛,想了一会之后就觉得是个概率dp的转移, 然而一开始想漏了个组合数的加权,但在+1的提醒下搞通了,但是分析了下,这是nmk的时间复杂度, 1e6还有个1e3的大T,emmm理论上会TLE的,但结果看网上题解,都是跟自己思路差不多,所以也是很迷. 嗯,转移过程其实很简单,dp[i][j]就是第i次抛了之后

Gym 101606F - Flipping Coins - [概率DP]

题目链接:https://codeforc.es/gym/101606/problem/F 题解: 假设 $f[i][j]$ 表示抛 $i$ 次硬币,有 $j$ 个硬币正面朝上的概率. 所以只有两种挑选硬币的情况: 1.正面硬币数量为 $[0,n-1]$,选择反面硬币抛,则正面硬币数量比原本增加 $1$ 或者不变. 2.正面硬币数量为 $n$,随便选择一个硬币抛,则正面硬币数量比原本减少 $1$ 或者不变. 因此可得状态转移方程: 对于 $j<n$,有 f[i+1][j+1]+=f[i][j]*

概率DP 2017 ICPC 乌鲁木齐 A Coins

题目链接:https://nanti.jisuanke.com/t/40512 题意:n个硬币,初始全是反面朝上,抛m次,每次抛k个,求最好情况硬币向上个数的期望 一个比较好的概率DP的总结:https://blog.csdn.net/myjs999/article/details/81022546 分析:很明显当硬币反面朝上次数大于k,直接抛这些,小于k时,这些反面朝上全部取的,不够的加正面朝上的,dp[i][j]表示抛i次后正面朝上有j个的概率,枚举每次抛的硬币里面正面朝上有t个,状态转移方

poj2096之概率DP入门

Collecting Bugs Time Limit: 10000MS   Memory Limit: 64000K Total Submissions: 2041   Accepted: 974 Case Time Limit: 2000MS   Special Judge Description Ivan is fond of collecting. Unlike other people who collect post stamps, coins or other material st

Collecting Bugs (概率dp)

Ivan is fond of collecting. Unlike other people who collect post stamps, coins or other material stuff, he collects software bugs. When Ivan gets a new program, he classifies all possible bugs into n categories. Each day he discovers exactly one bug

[ACM] poj 2096 Collecting Bugs (概率DP,期望)

Collecting Bugs Time Limit: 10000MS   Memory Limit: 64000K Total Submissions: 2026   Accepted: 971 Case Time Limit: 2000MS   Special Judge Description Ivan is fond of collecting. Unlike other people who collect post stamps, coins or other material st

概率dp poj2096

Collecting Bugs Time Limit: 10000MS   Memory Limit: 64000K Total Submissions: 2341   Accepted: 1126 Case Time Limit: 2000MS   Special Judge Description Ivan is fond of collecting. Unlike other people who collect post stamps, coins or other material s