• [CSP-S模拟测试]:石头剪刀布(rps)(概率DP)


    题目传送门(内部题9)


    输入格式

    第一行一个整数$n$。接下来$n$行每行$3$个非负整数$r_i,p_i,s_i$。


    输出格式

    一行一个实数表示答案。当你的答案与标准答案的绝对或相对误差不超过${10}^{-9}$时判为正确。


    样例

    样例输入:

    3
    300 0 0
    0 300 0
    0 0 300

    样例输出:

    6.333333333333


    数据范围与提示

    对于$10%$的数据,$n=1$。
    对于$30%$的数据,$nleqslant 10$。
    对于另外$10%$的数据,所有$r_i$均相等,所有$p_i$均相等。
    对于又另外$30%$的数据,$r_i=0$。
    对于$100%$的数据,$1leqslant nleqslant 50$,$r_i+p_i+s_i=300$。


    题解

    首先,这道题是一道假期望。

    用$g[i][j][k]$表示第$i+j+k$轮出了$i$个石头,$j$个剪刀,$k$个布的概率。

    用$dp[i][j][k][l]$表示前$i+j+k$轮出了$i$个石头,$j$个剪刀,$k$个布的概率。

    注意我们不是在$dp[i][j][k][x]$中取$max$,而是在$dp[i][j][k][x]+dp[i][j][k][x+1] imes 3$中取$max$。

    $g[i][j][k]$也非常好求,直接给出式子:$g[i][j][k]=g[i-1][j][k] imes r[t]+g[i][j-1][k] imes s[t]+g[i][j][k-1] imes p[t]$。

    注意$dp$和$g$的意义,所以对$g$的转移需要在$dp$之后。

    还有就是注意输入顺序是:石头、布、剪刀,即可。

    时间复杂度:$Theta(n^4)$。

    期望的分:$100$分。

    实际的分:$100$分。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    int n;
    long double w[100],z[100],c[100];
    long double C[51][51];
    long double g[51][51][51],dp1[51][51][51],dp2[51][51][51],dp3[51][51][51];
    long double ans;
    int main()
    {
    	scanf("%d",&n);
    	for(int i=0;i<=n;i++)
    	{
    		C[i][0]=1.0;
    		for(int j=1;j<=i;j++)
    			C[i][j]=C[i-1][j]+C[i-1][j-1];
    	}
    	for(int i=1;i<=n;i++)
    	{
    		cin>>w[i]>>c[i]>>z[i];//注意输入顺序
    		w[i]/=300.0;
    		z[i]/=300.0;
    		c[i]/=300.0;
    	}
    	g[0][0][0]=1.0;
    	for(int t=1;t<=n;t++)
    		for(int i=t;~i;i--)
    			for(int j=t-i;~j;j--)
    				for(int k=t-i-j;~k;k--)
    				{
    					if(i+j+k!=t)
    					{
    						if(i)dp1[i][j][k]+=dp1[i-1][j][k]*w[t];
    						if(j)dp1[i][j][k]+=dp1[i][j-1][k]*z[t];
    						if(k)dp1[i][j][k]+=dp1[i][j][k-1]*c[t];
    						dp1[i][j][k]+=g[i][j][k]*w[t];
    						if(i)dp2[i][j][k]+=dp2[i-1][j][k]*w[t];
    						if(j)dp2[i][j][k]+=dp2[i][j-1][k]*z[t];
    						if(k)dp2[i][j][k]+=dp2[i][j][k-1]*c[t];
    						dp2[i][j][k]+=g[i][j][k]*z[t];
    						if(i)dp3[i][j][k]+=dp3[i-1][j][k]*w[t];
    						if(j)dp3[i][j][k]+=dp3[i][j-1][k]*z[t];
    						if(k)dp3[i][j][k]+=dp3[i][j][k-1]*c[t];
    						dp3[i][j][k]+=g[i][j][k]*c[t];
    					}
    					if(i)g[i][j][k]+=g[i-1][j][k]*w[t];
    					if(j)g[i][j][k]+=g[i][j-1][k]*z[t];
    					if(k)g[i][j][k]+=g[i][j][k-1]*c[t];
    				}
    	for(int i=0;i<n;i++)
    		for(int j=0;i+j<n;j++)
    			for(int k=0;i+j+k<n;k++)
    				ans+=max(dp1[i][j][k]+3.0*dp2[i][j][k],max(dp2[i][j][k]+3.0*dp3[i][j][k],dp3[i][j][k]+3.0*dp1[i][j][k]))/(C[n][i+j+k]*(n-i-j-k));
    	cout<<fixed<<setprecision(12)<<ans<<endl;
    	return 0;
    }
    

    rp++

  • 相关阅读:
    一. web框架-----------ES6语法和VUE介绍(一)
    十.Django---framework框架 响应器(渲染器)
    【hiho1087】Hamiltonian Cycle
    【CF160E】Buses and People
    【51nod1672】区间交
    【洛谷P2915】Mixed Up Cows
    【模板】长链剖分
    【洛谷P4552】IncDec Sequence
    【CF1181C】Flag
    【CF1181D】Irrigation
  • 原文地址:https://www.cnblogs.com/wzc521/p/11331681.html
Copyright © 2020-2023  润新知