CF 540D. Bad Luck Island 概率dp

来源:互联网 发布:spycall软件多少钱 编辑:程序博客网 时间:2024/05/16 05:34

题目链接


题意:

一座岛上有三个物种,石头,剪刀和布,数量分别是R,S,R(均小于等于100),每天会有两个生物相遇,如果相克,会死掉一个生物。
问最后只剩下某个物种的概率是多少?分别输出只剩下石头、剪刀和布的三个值。


对于dp[r][s][p],无非两种情况,一是两个生物,相互克制,转移到子状态。否则,转移到自己。两种情况的概率比较好计算。比如说Rock与scissors相遇的概率为 r*s/C(r+s+p,2 )注意极限情况。


AC代码:

#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#include<vector>using namespace std;#define all(x) (x).begin(), (x).end()#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)#define mes(a,x,s)  memset(a,x,(s)*sizeof a[0])#define mem(a,x)  memset(a,x,sizeof a)#define ysk(x)  (1<<(x))typedef long long ll;typedef pair<int, int> pii;const int INF =0x3f3f3f3f;const int maxn=100    ;int R,S,P;double dp[maxn+5][maxn+5][maxn+5];int main(){   std::ios::sync_with_stdio(false);   while(cin>>R>>S>>P)   {        mem(dp,0);        dp[R][S][P]=1;        for(int r=R;r>=0;r--)        {            for(int s=S;s>=0;s--)            {                for(int p=P;p>=0;p--)                {                    if(s+r+p<2)  continue;                    double ret=0;                    if(r&&p)  ret+=   1.0*r*p/(1.0*(r+s+p)*(r+s+p-1)/2);// r*p/C(r+s+p,2)                    if(s&&r)  ret+=   1.0*s*r/(1.0*(r+s+p)*(r+s+p-1)/2);                    if(p&&s)  ret+=   1.0*p*s/(1.0*(r+s+p)*(r+s+p-1)/2);                    if(r&&p)  dp[r-1][s][p]+= dp[r][s][p]*1.0*r*p/(1.0*(r+s+p)*(r+s+p-1)/2)/ret;                    if(s&&r)  dp[r][s-1][p]+= dp[r][s][p]*1.0*s*r/(1.0*(r+s+p)*(r+s+p-1)/2)/ret;                    if(p&&s)  dp[r][s][p-1]+= dp[r][s][p]*1.0*p*s/(1.0*(r+s+p)*(r+s+p-1)/2)/ret;                }            }        }        double ans[3]={0,0,0};        for1(i,R) ans[0]+=dp[i][0][0];        for1(i,S) ans[1]+=dp[0][i][0];        for1(i,P) ans[2]+=dp[0][0][i];        printf("%.12f %.12f %.12f\n",ans[0],ans[1],ans[2]);   }   return 0;}
0 0
原创粉丝点击