zoukankan      html  css  js  c++  java
  • BZOJ 4008: [HNOI2015]亚瑟王

    略显麻烦并且套路的概率DP题,被一个初始化坑了好久

    首先根据期望的线性性我们可以求出每张卡使用的概率然后计算答案

    我们先不谈这个概率怎么求,先来想一个一眼能设出来的DP,令(f_{i,j})表示前(i)张牌里选(j)张的概率

    考虑它怎么转移,显然是从(f_{i-1,j})(f_{i-1,j-1})转移过来,然后我们发现按这个顺序DP有一个好处就是一张牌前面有多少张牌被发动了是确定的

    那么这张牌被考虑的次数显然也可以统计出来了,容易得到此时的转移方程

    [f_{i,j}=f_{i,j}+f_{i-1,j} imes (1-p_i)^{r-j} ]

    [f_{i,j}=f_{i,j}+f_{i-1,j-1} imes [1-(1-p_i)^{r-j+1}] ]

    那么我们求出了看似没用的(f_{i,j})能干嘛呢,考虑我们推导(f_{i,j})的时候根据一张牌前面有多少张发动了技能就可以推出这张牌被考虑的次数,那么我们同理可以推导出答案:

    [P(i)=sum_{j=0}^r f_{i-1,j} imes [1-(1-p_i)^{r-j}] ]

    注意关键的边界:第一张牌!稍加分析我们有:

    [f_{1,0}=(1-p_i)^r;P(1)=f_{1,1}=1-(1-p_i)^r ]

    那么这道题就算是做完了,复杂度(O(t imes n imes r))

    #include<cstdio>
    #define RI register int
    #define CI const int&
    using namespace std;
    const int N=225,M=135;
    int t,n,m,d[N]; double ans,tp,p[N][M],f[N][N];
    int main()
    {
        for (scanf("%d",&t);t;--t)
        {
            RI i,j; for (scanf("%d%d",&n,&m),i=1;i<=n;++i)
            scanf("%lf%d",&tp,&d[i]),p[i][0]=1,p[i][1]=1.0-tp;
            for (i=1;i<=n;++i) for (j=2;j<=m;++j) p[i][j]=p[i][j-1]*p[i][1];
            for (f[1][0]=p[1][m],f[1][1]=1.0-p[1][m],i=2;i<=n;++i) for (j=0;j<=m;++j)
            f[i][j]=f[i-1][j]*p[i][m-j]+(j?f[i-1][j-1]*(1.0-p[i][m-j+1]):0);
            for (ans=(1.0-p[1][m])*d[1],i=2;i<=n;++i)
            {
                for (tp=j=0;j<=m;++j) tp+=f[i-1][j]*(1.0-p[i][m-j]);
                ans+=1.0*tp*d[i];
            }
            printf("%.10lf
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    php composer 相关及版本约束等小技巧
    Jquery 获取表单值如input,select等方法
    Apache benchmark 压力测试工具
    Linux中的随机数文件 /dev/random /dev/urandom
    redis持久化
    Python---装饰器
    高仿拉手网底部菜单实现FragmentActivity+Fragment+RadioGroup
    python实现二叉树和它的七种遍历
    Spring AOP应用实例demo
    二维数组的列排序
  • 原文地址:https://www.cnblogs.com/cjjsb/p/12241635.html
Copyright © 2011-2022 走看看