zoukankan      html  css  js  c++  java
  • poj2096_概率dp

    逆着递推求解
    题意:
    一个软件有s个子系统,会产生n种bug
    某人一天发现一个bug,这个bug属于一个子系统,属于一个分类
    每个bug属于某个子系统的概率是1/s,属于某种分类的概率是1/n
    问发现n种bug,每个子系统都发现bug的天数的期望。

    求解:
    dp[i][j]表示已经找到i种bug,j个系统的bug后要达到目标状态的天数的期望
    dp[n][s]=0;要求的答案是dp[0][0];
    dp[i][j]可以转化成以下四种状态:
    dp[i][j],发现一个bug属于已经有的i个分类和j个系统。概率为(i/n)*(j/s);
    dp[i][j+1],发现一个bug属于已有的分类,不属于已有的系统.概率为 (i/n)*(1-j/s);
    dp[i+1][j],发现一个bug属于已有的系统,不属于已有的分类,概率为 (1-i/n)*(j/s);
    dp[i+1][j+1],发现一个bug不属于已有的系统,不属于已有的分类,概率为 (1-i/n)*(1-j/s);
    整理便得到转移方程
    dp[i][j]=p1*dp[i+1][j+1]+p2*dp[i+1][j]+p3*dp[i][j+1]+p4*dp[i][j]+1; //dp[i][j]表示的就是到达状态i,j的期望,+1是因为一天后

    =>dp[i][j]=(p1*dp[i+1][j+1]+p2*dp[i+1][j]+p3*dp[i][j+1]+1)/(1-p4); 

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <cstdlib>
     6 #include <cmath>
     7 #include <set>
     8 #include <map>
     9 #include <queue>
    10 #include <vector>
    11 #define INF 0x3f3f3f3f
    12 using namespace std;
    13 
    14 double dp[1010][1010];
    15 int main()
    16 {
    17     int n, s;
    18     scanf("%d %d", &n, &s);
    19     for(int i = n; i >= 0; i--)
    20     {
    21         for(int j = s; j >= 0; j--)
    22         {
    23             if(i == n && j == s)
    24                 continue;
    25             dp[i][j] = ((n-i)*j*dp[i+1][j]+i*(s-j)*dp[i][j+1]+(n-i)*(s-j)*dp[i+1][j+1]+n*s)*1.0/(n*s-i*j); 
    26         }
    27     }
    28     printf("%.4f
    ", dp[0][0]);
    29     return 0;
    30 }
  • 相关阅读:
    password
    bzoj 1458: 士兵占领
    国家集训队2011 happiness
    cogs 2051. 王者之剑
    uva 10779 Collectors Problem
    [Jxoi2012]奇怪的道路
    天神下凡
    藏宝图
    黑红树
    愤怒的小鸟
  • 原文地址:https://www.cnblogs.com/luomi/p/5693049.html
Copyright © 2011-2022 走看看