zoukankan      html  css  js  c++  java
  • 【期望DP】[UVA1498] Activation

    显然是概率DP

    我们用dp[i][j]表示队伍中有i个人,lyk的小迷妹现在排在j这个位置时的概率大小

    不难列出下列转移方程:

    (显然已经排到前面k个位置的时候是要加上爆炸也就是p4的概率的)


     

    $$f[i][1]=f[i][1]*p1+f[i][i]*p2+p4$$
    $$f[i][j]=f[i][j]*p1+f[i][j-1]*p2+f[i-1][j-1]*p3+p4(j∈[2,k])$$
    $$f[i][j]=f[i][j]*p1+f[i][j-1]*p2+f[i-1][j-1]*p3(j∈[k+1,i])$$

     


     


    这是一个从前往后递推的过程,但是十分不和谐的是:f[i][1]的递推式中出现了$f[i][i]$,显然我们要想办法把这玩意儿给消掉

    先化简,把两边同类项合并了,结果是这样的:

     


     

    $$f[i][1]=f[i][i]*frac{p2}{1-p1}+frac{p4}{1-p1}$$
    $$f[i][j]=f[i][j-1]*frac{p2}{1-p1}+f[i-1][j-1]*frac{p3}{1-p1}+frac{p4}{1-p1}(j∈[2,k])$$
    $$f[i][j]=f[i][j-1]*frac{p2}{1-p1}+f[i-1][j-1]*frac{p3}{1-p1}(j∈[k+1,i])$$


     

    由于从前往后递推,在求f[i][j]是,f[i-1][]的所有值我们已经求出来了,所以可以看做常数,p1,p2,p3,p4显然已知,也是常数

    所以我们可以把这玩意为当做方程解,我们只要把f[i][i]看做未知数,在不断的迭代下去即可

    大概是这个样子:

     



    不妨令a=$frac{p2}{1-p1}$,$b=frac{p3}{1-p1}$,$c=frac{p4}{1-p1}$

    设$C_j=f[i-1][j-1]*c+d$

    则有:$$f[i][1]=f[i][i]*a+c$$
    $$f[i][2]=f[i][1]*a+C_2$$
    (然后把f[i][1]代入②式,依次类推......)


     

    最后我们把式子最后面的常数部分设成sol

    显然可以得到$$f[i][i]=a^{i}*f[i][i]+sol$$

    也就是说
    $$f[i][i]=frac{sol}{1-a^i}$$

    这样填完所有$f[][]$的表之后这道题也就解决了qaq

    不过因为空间限制,我们要压掉f[][]第一维(f[i][]的值只与f[i-1][]有关)

    代码实现在这里哦~

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 inline int read(){
     4     int ans=0,f=1;char chr=getchar();
     5     while(!isdigit(chr)){if(chr=='-')f=-1;chr=getchar();}
     6     while(isdigit(chr)) {ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
     7     return ans*f;
     8 }const int M = 2005;int n,m,k;
     9 double f[2][M],p1,p2,p3,p4,a,b,c,v[M],p[M];
    10 int main(){
    11     while(~scanf("%d%d%d%lf%lf%lf%lf",&n,&m,&k,&p1,&p2,&p3,&p4)){
    12         if(fabs(p4)<=1e-5) {puts("0.00000");continue;}//p4为0时显然不可能
    13         a=p2/(1-p1),b=p3/(1-p1),c=p4/(1-p1);
    14         v[0]=1;for(int i=1;i<=n;i++) v[i]=v[i-1]*a;//预处理a的i次方
    15         p[1]=c;f[1][1]=p4/(1-p1-p2);
    16         for(int i=2;i<=n;i++){
    17             double sol=0;
    18             for(int j=2;j<=k;j++) p[j]=f[i-1&1][j-1]*b+c;
    19             for(int j=k+1;j<=i;j++) p[j]=f[i-1&1][j-1]*b;//求每一个方程式的常数项
    20             for(int j=1;j<=i;j++) sol+=v[i-j]*p[j];//求最后一个式子f[i][i]=......的常数项
    21             f[i&1][i]=sol/(1-v[i]);
    22             f[i&1][1]=f[i&1][i]*a+c;//回代消元
    23             for(int j=2;j<i;j++) f[i&1][j]=f[i&1][j-1]*a+p[j];//回去填表
    24         }printf("%.5lf
    ",f[n&1][m]);
    25     }
    26     return 0;
    27 }

     

  • 相关阅读:
    Vue 项目结构介绍
    使用命令行创建 Vue 项目
    GitHub无法访问怎么办?-- 已解决
    Spa 单页面应用简介
    JetBrains WebStorm 常用快捷键总结
    使用 WebStorm + Vue 写一个九九乘法表
    使用 WebStorm 2018 运行第一个 Vue 程序
    小工具
    elasticsearch安装部署
    命令行连接ftp
  • 原文地址:https://www.cnblogs.com/zhenglw/p/11299699.html
Copyright © 2011-2022 走看看