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\n", (double)ans);
    }
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/galaxies/p/bzoj4008.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值