zoukankan      html  css  js  c++  java
  • bzoj2318 Spoj4060 game with probability Problem

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

    【题解】

    令f[i]表示剩i个石子,A先手赢的概率;g[i]表示剩i个石子,A后手赢的概率。

    如果想选的话,f[i]可以通过g[i-1]和g[i]转移来,系数推推即可。同理g[i]可以通过f[i-1]和f[i]转移来。

    然后这是两个方程,我们要求解的是f[i]和g[i],解方程 化简即可。

    考虑如果f[i-1]<g[i-1]也就是说后手比较优,那么A想让石头来到i-1,这样就出现了i-1石头,B先手A后手,比较优,所以都想选。

    反之都不想选。

    直接转移即可,复杂度O(Tn)。

    考虑复杂度太大,加上打表打表可以知道,当n很大的时候,f和g基本不变,我们设定阈值10w,超过就当做10w做即可。

    # 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 = 5e5 + 10;
    const int mod = 1e9+7;
    
    # define RG register
    # define ST static
    
    int T, n;
    double p, q;
    double f[M], g[M];
    // 剩i个石子,A先手赢的概率
    // 剩i个石子,A后手赢的概率 
    
    inline void sol() {
        cin >> n >> p >> q;
        f[0] = 0.0, g[0] = 1.0; 
        for (int i=1; i<=n && i<=100000; ++i) {
            if(f[i-1] <= g[i-1]) {
                f[i] = ((1.0-p) * q * f[i-1] + p * g[i-1]) / (1.0-(1-p)*(1-q)); 
                g[i] = ((1.0-q) * p * g[i-1] + q * f[i-1]) / (1.0-(1-p)*(1-q));
            } else {
                 f[i] = (p * (1.0-q) * f[i-1] + (1.0-p) * g[i-1]) / (1.0-p*q);
                g[i] = (q * (1.0-p) * g[i-1] + (1.0-q) * f[i-1]) / (1.0-p*q);
            }
        }
        printf("%.6lf
    ", f[(n > 100000) ? 100000 : n]); 
    }
    
    int main() {
        cin >> T;
        while(T--) sol();
        return 0;
    }
    View Code
  • 相关阅读:
    JAVA类与对象(十)-----抽象类
    JAVA类与对象(九)------多态
    JAVA类与对象(八)-----重写
    JAVA类与对象(七)------继承
    Mysql与Oracle区别
    redis缓存技术学习
    关于java中B/S架构
    关于java中C/S架构,创建服务器和客户端
    JQuery 轮播图片
    Kendo中ListView 无分页控件显示和有分页控件显示
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj2318.html
Copyright © 2011-2022 走看看