• Spoj4060 game with probability Problem


    题目链接:Click here

    Solution:

    刚开始还以为博弈论加概率,然而并不是...

    设两个状态:(f(i))表示当前剩下(i)个石头时,先手的获胜概率,(g(i))为后手的获胜概率(注:先后手定义参照博弈论。。。)

    我们再设(p')表示(A)抛硬币为正面朝上的概率,(q')表示(B)抛硬币为正面朝上的概率,则易得转移式:

    [f(i)=p'g(i-1)+(1-p')g(i)\ g(i)=q'f(i-1)+(1-q')f(i) ]

    现在我们是不能直接进行dp的,因为方程中存在与它同阶段的值,则我们需要进行转化

    [f(i)=p'g(i-1)+(1-p')(q'f(i-1)+(1-q')f(i))\ f(i)=p'g(i-1)+(q'f(i-1)+(1-q')f(i))-p'(q'f(i-1)+(1-q')f(i))\ f(i)=p'g(i-1)+q'f(i-1)+(1-q')f(i)-p'q'f(i-1)-p'(1-q')f(i)\ f(i)=p'g(i-1)+q'f(i-1)-p'q'f(i-1)+(1-p')(1-q')f(i)\ f(i)=frac{p'g(i-1)+q'(1-p')f(i-1)}{1-(1-p')(1-q')} ]

    类似的,我们同样可以得到关于(g(i))的式子:

    [g(i)=frac{q'f(i-1)+p'(1-q')g(i-1)}{1-(1-p')(1-q')} ]

    则这就是最终的转移方程式,但是,我们的(p'q')的定义是不同于题目给定的(pq)的,则我们需要具体分情况讨论:

    (f(i-1)>g(i-1))时,明显的,(A)不希望拿走石头,(B)也不希望拿走石头,则他们都希望硬币反面朝上

    (f(i-1)<g(i-1))时,(A)是希望拿走石头的,(B)也是希望拿走石头的,则他们都希望硬币正面朝上

    到这里,我们还是有一个问题并没有解决,就是(n)过于大,事实上,(n)越大,概率越趋向于一个定值,而题目只要求保留6位数,则我们只要让(n)到1000就行了QAQ

    Code:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1001;
    int n;double q,p,f[N],g[N];
    double rev(double x){return 1.0-x;}
    int read(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    	return x*f;
    }
    int main(){
    	int T=read();
    	while(T--){
    		n=read();
    		scanf("%lf%lf",&p,&q);
    		f[0]=0,g[0]=1;n=min(n,N-1);
    		for(int i=1;i<=n;i++){
    			double gl1=p,gl2=q;
    			if(f[i-1]>g[i-1]) gl1=rev(gl1),gl2=rev(gl2);
    			f[i]=(1.0*gl2*(1.0-gl1)*f[i-1]+gl1*g[i-1])/(1-rev(gl1)*rev(gl2));
    			g[i]=(1.0*gl1*(1.0-gl2)*g[i-1]+gl2*f[i-1])/(1-rev(gl1)*rev(gl2));
    		}printf("%.6lf
    ",f[n]);
    	}return 0;
    }
    
  • 相关阅读:
    安装ActivePython
    安装Selenium
    安装setuptools与pip
    windows下测试环境搭建--Python安装
    编程语言 标记语言 脚本语言
    XMLHttpRequest 对象
    事务
    jsp
    Cookie案例-显示用户的上次访问时间代码实现
    事务处理
  • 原文地址:https://www.cnblogs.com/NLDQY/p/11171477.html
Copyright © 2020-2023  润新知