zoukankan      html  css  js  c++  java
  • bzoj4008 [HNOI2015]亚瑟王

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4008

    【题解】

    我们把牌看成人吧好说明qwq

    f[i,j]表示第i个人得到了j次机会的概率。

    f[i,j]=f[i-1,j]*(1-p[i-1])^j+f[i-1,j+1]*(1-(1-p[i-1])^(j+1))

    (前一个人得到了j次机会,都没有把握住;前一个人得到了j+1次机会,把握住了一次)

    明显可以dp。

    统计答案的话,就是

    ΣΣf[i,j]*(1-(1-p[i])^j)*d[i]

    (考虑每个人得到机会的概率,他们只要一次把握住就能造成伤害)

    # include <stdio.h>
    # include <string.h>
    # 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 = 310;
    
    # define RG register
    # define ST static
    
    int n, r;
    ld p[M], d[M];
    ld g[M][M], f[M][M]; 
    
    int main() {
        int T; scanf("%d", &T);
        while(T--) {
            memset(f, 0, sizeof f); 
            scanf("%d%d", &n, &r);
            p[0] = 0.0; 
            for (int i=1; i<=n; ++i) {
                double pd, pe; scanf("%lf%lf", &pd, &pe);
                p[i] = (ld)pd; d[i] = (ld)pe; 
            }
            for (int i=0; i<=n; ++i) {
                g[i][0] = 1.0; 
                for (int j=1; j<=r; ++j)
                    g[i][j] = g[i][j-1]*(1.0-p[i]);
            }
            // 第i个人得到了j次机会 
            ld ans = 0.0; 
            f[0][r] = 1.0; 
            for (int i=1; i<=n; ++i) 
                for (int j=1; j<=r; ++j) { 
                    f[i][j] = f[i-1][j]*g[i-1][j] + f[i-1][j+1]*(1.0-g[i-1][j+1]);     
                    ans = ans + f[i][j]*(1-g[i][j])*(ld)d[i];
                }
            printf("%.10lf
    ", (double)ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    PAT1038
    PAT1034
    PAT1033
    PAT1021
    PAT1030
    PAT1026
    PAT1063
    PAT1064
    PAT1053
    PAT1025
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj4008.html
Copyright © 2011-2022 走看看