• 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;
    }
    
  • 相关阅读:
    Android Studio设置字体和主题
    Android 使用shape定义不同控件的的颜色、背景色、边框色
    Linux下mysql的常用操作
    部署腾讯云(CentOS6.6版本,jdk1.7+tomcat8+mysql)
    在linux下如何使用yum查看安装了哪些软件包
    Tomcat下wtpwebapps文件夹 和 webapps文件夹区别
    安卓开源框架SlidingMenu使用
    Android_scaleType属性
    Android_Jar mismatch! Fix your dependencies
    操作系统原理之进程管理(第二章)
  • 原文地址:https://www.cnblogs.com/cjjsb/p/12241635.html
Copyright © 2020-2023  润新知