码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 2318 spoj 4060(KPGAME)

时间:2015-03-31 16:04:05      阅读:195      评论:0      收藏:0      [点我收藏+]

标签:游戏   博弈   bzoj   spoj   

Description



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

Solution



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

g[i]=q?f[i?1]+(1?q)?f[i]

f[i],g[i]
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)

搞定~

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;
}

bzoj 2318 spoj 4060(KPGAME)

标签:游戏   博弈   bzoj   spoj   

原文地址:http://blog.csdn.net/mlzmlz95/article/details/44780237

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!