• poj2096 Collecting Bugs


    传送门:http://poj.org/problem?id=2096

    【题解】

    看到有人在uoj群上问这个……就去看了看…

    顺便复习下概率dp

    $f_{i,j}$表示这个人已经找出了$i$种系统的bug,和$j$种bug的期望步数。

    每次有4种转移:

    1. 发现了新的bug种类,属于新的系统,那么是$f_{i+1, j+1}$,概率是$i/s * j/n$,设两者相乘为$a$;

    2. 发现了新的bug种类,属于原有系统,那么是$f_{i, j+1}$,概率是$(s-i)/s * (n-j)/n$,设两者相乘为$b$;

    3. 发现了原有bug种类,属于新的系统,那么是$f_{i+1, j}$,概率是$i/s * (n-j)/n$,设两者相乘为$c$;

    4. 发现了原有bug种类,属于原有系统,那么是$f_{i,j}$,概率是$(n-i)/s * (n-j)/n$,设两者相乘为$d$

    所以$f_{i,j} = 1 + a + b + c + d$,把$f_{i,j}$移项即可得到转移式子。

    答案为$f_{0,0}$,这是经典的从后往前推概率dp。复杂度$O(ns)$。

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 1e3 + 10;
    const int mod = 1e9+7;
    
    int n, s;
    ld f[M][M];
    
    inline void prtld(const ld& x) {
        printf("%.4lf
    ", (double)x);
    }
    
    // 发现了i个系统的bug,j种bug的方案数的期望 
    // 1. 发现了新的bug种类,属于新的系统
    // 2. 发现了新的bug种类,属于原有系统
    // 3. 发现了原有bug种类,属于新的系统
    // 4. 发现了原有bug种类,属于原有系统 
    
    int main() {
        cin >> n >> s;  
        for (int i=s; ~i; --i)
            for (int j=n; ~j; --j) {
                if(i == s && j == n) continue;
                f[i][j] = (f[i+1][j+1] * (s-i) * (n-j) + f[i+1][j] * (s-i) * j + f[i][j+1] * i * (n-j) + n * s) / (n * s - i * j);
            }
        prtld(f[0][0]); 
        return 0;
    }
    View Code
  • 相关阅读:
    字典_序列解包用于列表元组字典
    字典_序列解包用于列表元组字典
    字典_元素的访问_键的访问_值的访问_键值对的访问
    字典_特点_4种创建方式_普通-dict
    元组_生成器推导式创建元组-总结
    MySql高级
    技术点
    全文检索ElasticSearch
    数仓管理
    SpringCache
  • 原文地址:https://www.cnblogs.com/galaxies/p/poj2096.html
Copyright © 2020-2023  润新知