bzoj 2318 spoj 4060(KPGAME)

3 篇文章 0 订阅
1 篇文章 0 订阅

Description



Alice和Bob在玩一个游戏。有n个石子在这里,Alice和Bob轮流投掷硬币,如果正面朝上,则从n个石子中取出一个石子,否则不做任何事。取到最后一颗石子的人胜利。Alice在投掷硬币时有p的概率投掷出他想投的一面,同样,Bob有q的概率投掷出他相投的一面。
现在Alice先手投掷硬币,假设他们都想赢得游戏,问你Alice胜利的概率为多少。

Solution



f[i]iAg[i]A
观察到,如果 f[i1]>g[i1] ,A显然是不愿意再取石子的,同样B为了获胜也不愿意取石子。
反之 f[i1]<g[i1] ,双方都想取石子,那么显然的
f[i]=pg[i1]+(1p)g[i]

g[i]=qf[i1]+(1q)f[i]

f[i],g[i]
f[i]=pg[i1]+(1p)qf[i1]1(1p)(1q)

g[i]=qf[i1]+(1q)pg[i1]1(1p)(1q)

搞定~

Code

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
inline void read(int &t) {
    int f = 1;char c;
    while (c = getchar(), c < '0' || c > '9') if (c == '-') f = -1;
    t = c - '0';
    while (c = getchar(), c >= '0' && c <= '9') t = t * 10 + c - '0';
    t *= f;
}
const int N = 1005;
double f[N], g[N];
int main() {
    int T, n;
    read(T);
    while (T--) {
        read(n);
        n = min(n, 1000);
        double p, q;
        scanf("%lf%lf", &p, &q);
        f[0] = 0, g[0] = 1;
        for (int i = 1; i <= n; ++i) {
            if (f[i - 1] > g[i - 1])    p = 1 - p, q = 1 - q;
            f[i] = (p * g[i - 1] + (1 - p) * q * f[i - 1]) / (1 - (1 - p) * (1 - q));
            g[i] = (q * f[i - 1] + (1 - q) * p * g[i - 1]) / (1 - (1 - p) * (1 - q));
            if (f[i - 1] > g[i - 1])    p = 1 - p, q = 1 - q;
        }
        printf("%.8lf\n", f[n]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值