Codeforces Round #301 (Div. 2)D. Bad Luck Island(概率DP)

题目链接:https://codeforces.com/problemset/problem/540/D

 

题目大意:一个岛上有x个石头,y个剪刀,z个布,每两个东西打架的概率相等,石头打败剪刀,剪刀打败布,布打败石头,求最后只剩石头、剪刀、布的概率

 

题目思路:dp[i][j][k]分别表示剩下i个石头 j个剪刀 k个布。转移方程很类似,以少了个石头举例,也就是dp[i-1][j][k],少了个石头就说明石头跟布打架了,石头跟布打架的方案数是i*k,也就是石头数量乘以布的数量,所有的方案数是i*j+i*k+j*k也就是石头跟剪刀,石头跟布,剪刀跟布的方案数之和。那么dp[i-1][j][k]+=dp[i][j][k]*(1.0*i*k)/(1.0*i*j+i*k+j*k),其他所有情况与此同理

 

以下是代码:

#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(ll i=a;i>=b;i--)
#define ll long long
const ll MAXN = 5e5+5;
const ll MOD = 1e9+7;
int r,s,p;
double dp[105][105][105];
int main()
{
    while(~scanf("%d%d%d",&r,&s,&p)){
        memset(dp,0,sizeof(dp));
        dp[r][s][p]=1;
        per(i,r,0){
            per(j,s,0){
                per(k,p,0){
                    int temp=i*j+i*k+j*k;
                    if(i&&k)dp[i-1][j][k]+=dp[i][j][k]*(1.0*i*k)/(1.0*temp);
                    if(j&&i)dp[i][j-1][k]+=dp[i][j][k]*(1.0*i*j)/(1.0*temp);
                    if(k&&j)dp[i][j][k-1]+=dp[i][j][k]*(1.0*j*k)/(1.0*temp);
                }
            }
        }
        double ans1=0,ans2=0,ans3=0;
        rep(i,1,r)ans1+=dp[i][0][0];
        rep(i,1,s)ans2+=dp[0][i][0];
        rep(i,1,p)ans3+=dp[0][0][i];
        printf("%.9lf %.9lf %.9lf\n",ans1,ans2,ans3);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值