cf 540D D. Bad Luck Island 概率dp

D. Bad Luck Island

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

The Bad Luck Island is inhabited by three kinds of species: r rocks, s scissors
and p papers. At some moments of time two random individuals meet (all pairs of individuals can meet equiprobably), and if they belong to different species,
then one individual kills the other one: a rock kills scissors, scissors kill paper, and paper kills a rock. Your task is to determine for each species what is the probability that this species will be the only one to inhabit this island after a long enough
period of time.

Input

The single line contains three integers rs and p (1?≤?r,?s,?p?≤?100) —
the original number of individuals in the species of rock, scissors and paper, respectively.

Output

Print three space-separated real numbers: the probabilities, at which the rocks, the scissors and the paper will be the only surviving species, respectively. The answer will be considered correct if the relative or absolute error of each number doesn‘t exceed 10?-?9.

Sample test(s)

input

2 2 2

output

0.333333333333 0.333333333333 0.333333333333

input

2 1 2

output

0.150000000000 0.300000000000 0.550000000000

input

1 1 3

output

0.057142857143 0.657142857143 0.285714285714

链接:http://codeforces.com/contest/540/problem/D

题意:一个岛上有石头人,剪刀人,布人,每天会有两个人相遇,根据相克会死掉一个人。问最后只剩下石头人的几率,只剩剪刀人的几率,布人的几率。

做法:dp[i][j][k] 代表有i个石头,j个剪刀,k个布的几率。

以剪刀和布相遇为例,会有转移 dp[i][j][k-1]+=dp[i][j][k]*j*k/(i+j+k)/(i+j+k-1) 。

但是这是不够的,因为还有平局的情况。平局的时候,状态又转移回了dp[i][j][k],又从原状态开始转移,所以转移的比例还是一样的。

所以可以直接把 所有的转移几率相加,然后在转移的时候除掉。转移方程变为dp[i][j][k-1]+=dp[i][j][k]*j*k/(i+j+k)/(i+j+k-1)/tem;

tem为不是平局的几率总和。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <malloc.h>
#include <ctype.h>
#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#include <stack>
#include <queue>
#include <vector>
#include <deque>
#include <set>
#include <map>
#define INF 999999999
#define eps 0.00001
#define LL __int64d
#define pi acos(-1.0)

double dp[110][110][110];
int main()
{
	int shi,jian,bu;
	while(scanf("%d%d%d",&shi,&jian,&bu)!=EOF)
	{
		memset(dp,0,sizeof dp);
		dp[shi][jian][bu]=1;
		for(int i=shi;i>=0;i--)
		{
			for(int j=jian;j>=0;j--)
			{
				for(int k=bu;k>=0;k--)
				{
					//printf("%d %d %d %lf\n ",i,j,k,dp[i][j][k]);
					if(i+j==0||i+k==0||j+k==0)
						continue;

					double tem=0;
					if(k!=0)
						tem+=1.0*j*k/(i+j+k)/(i+j+k-1);
					if(j!=0)
						tem+=1.0*j*i/(i+j+k)/(i+j+k-1);
					if(i!=0)
						tem+=1.0*i*k/(i+j+k)/(i+j+k-1);

					if(k!=0)
					dp[i][j][k-1]+=dp[i][j][k]*j*k/(i+j+k)/(i+j+k-1)/tem;
					if(j!=0)
					dp[i][j-1][k]+=dp[i][j][k]*j*i/(i+j+k)/(i+j+k-1)/tem;
					if(i!=0)
					dp[i-1][j][k]+=dp[i][j][k]*i*k/(i+j+k)/(i+j+k-1)/tem;
				}
			}
		}
		double aj=0;
		double as=0,ab=0;
		for(int i=1;i<=jian;i++)
		{
			aj+=dp[0][i][0];
		}
		for(int i=1;i<=shi;i++)
		{
			as+=dp[i][0][0];
		}
		for(int i=1;i<=bu;i++)
		{
			ab+=dp[0][0][i];
		}
		printf("%.9lf %.9lf %.9lf\n",as,aj,ab);
	}
	return 0;
}
时间: 2024-10-02 06:35:09

cf 540D D. Bad Luck Island 概率dp的相关文章

CodeForces 540D Bad Luck Island 概率dp

CodeForces 540D 应该是简单概率dp,由于写得少显得十分蠢萌 求期望逆推,求概率正推,大概是这么个意思,贴一发留恋 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define db double const int maxn=108; db dp[maxn][maxn][maxn]; int main() { int i,j,n,m,k,p; whi

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

D. Bad Luck Island The Bad Luck Island is inhabited by three kinds of species: r rocks, s scissors and p papers. At some moments of time two random individuals meet (all pairs of individuals can meet equiprobably), and if they belong to different spe

Codeforces Div.301D Bad Luck Island(概率dp+记忆化搜索)

一道概率dp问题. 题目链接:http://codeforces.com/contest/540/problem/D 题目大意:一个岛上有r个石头,s个剪子,p个布,他们之间随机挑出两个相遇,如果不是相同物种,就会有一个消失,分别求出最后这座岛上只剩下一个物种的概率. 我们用dp[i][j][k]来存储i个石头,j个剪刀,k个布时,某物种的存活概率,共dp三次,算出三个物种分别的概率. 首先,我们需要把对应想求的物种概率初始化,这里以石头为例,那么对于i从1到r,不难理解dp[i][0][0]=

cf540D. Bad Luck Island(概率dp)

题意 岛上有三个物种:剪刀$s$.石头$r$.布$p$ 其中剪刀能干掉布,布能干掉石头,石头能干掉剪刀 每天会从这三个物种中发生一场战争(也就是说其中的一个会被干掉) 问最后仅有$s/r/p$物种生存的概率 Sol 还是想复杂了啊,我列的状态时$f[i][j], g[i][j],t[i][j]$分别表示第$i$天,$j$个$s, r, p$活着的概率 然而转移了一下午也没转移出来.. 标算比我简单的多,直接设$f[i][j][k]$表示剩下$i$个$s$,$j$个$r$,$k$个$p$的概率 然

CF 301div2 D. Bad Luck Island

D. Bad Luck Island The Bad Luck Island is inhabited by three kinds of species: r rocks, s scissors and p papers. At some moments of time two random individuals meet (all pairs of individuals can meet equiprobably), and if they belong to different spe

Codeforces 540D Bad Luck Island - 概率+记忆化搜索

[题意] 一个岛上有三种生物A,B,C,各有多少只在输入中会告诉你,每种最多100只 A与B碰面,A会吃掉B, B与C碰面,B会吃掉C, C与A碰面,C会吃掉A...忍不住想吐槽这种环形食物链 碰面是随机的.到最后岛上只剩下一种生物,问这种生物分别是A,B,C的概率是多少. [题解] 其实很简单,这题,状态方程很好想.. 设dp[i][j][k]为生物A有i只,生物B有j只,生物C有k只的概率情况,显然dp的返回值应该有三个,分别是最后剩下该种生物的概率 那么我们考虑状态转移的情况. 如果A与B

ZOJ 2949 Coins of Luck(概率dp求期望)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1948 Luck is the key to life. When I have to decide something, I will make my decision by flipping a coin. And then, I have two things to do. First, I have the decision made. Second, I g

CF540D Bad Luck Island(期望dp)

传送门 解题思路 比较容易的一道期望\(dp\),设\(f[i][j][k]\)表示石头\(i\)个,剪刀\(j\)个,步子\(l\)个.然后转移的时候用组合数算一下就好了. 代码 #include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; const int MAXN = 105; int r,s,p; double f[MAXN][M

CF#301 D:Bad Luck Island (概率dp)

D:Bad Luck Island 一个岛上有r个石头,s个剪子,p个布,他们之间随机挑出两个相遇,如果不是相同物种,就会有一个消失,分别求出最后这座岛上只剩下一个物种的概率. 我们用dp[i][j][k]来存储剩下 i 个石头, j 个剪刀,k 个布时的概率,共dp三次: 如果石头与剪刀碰面,概率是 p1 = i*j / (i*j+j*k+k*i),这种情况下,剪刀会被石头吃掉,所以石头的数目减少1,表现出来是dp[i-1][j][k] = p1*dp[i][j][k]  (dp的3的返回值均