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

原題鏈接:

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

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


題意:有三種人,r,s,p,其中r可以殺死s,s可以殺死p,p可以殺死r,任意時間,只要兩種不同的人相遇就會殺死其中一方,已知初始r,s,p的人數,求在無限長時間以後分別只剩r,s,p類人的概率。

思路:設某一時間的人數狀態爲(i,j,k),則下一狀態可以爲(i-1,,j,k),(i,j-1,k) , (i,j,k-1),若dp[i][j][k]表示這一狀態出現的概率,則以下一狀態爲(i-1,j,k)爲例,其中任意不同類兩人相遇的情況爲(i*j+j*k+i*k),而i死去一個,則爲i和k相遇的情況(i*k),即dp[i-1][j][k]+=dp[i][j][k]*(i*k)/(i*j+j*k+i*k)。有一些邊界條件要注意,還有輸出誤差要求是10-9。


代碼:

#include "stdio.h"
#include "iostream"
#include "string.h"
#include "stdlib.h"
#include "algorithm"
#include "math.h"
#include "map"
#include "queue"
#include "stack"
using namespace std;
const int INF=0x3f3f3f3f;
const int MAXN=100005;
typedef long long LL;

int a,b,c;
double dp[101][101][101];

int cc[3][3]={-1,0,0,0,-1,0,0,0,-1};

void getdp(int i,int j,int k,int w)
{
	double s=i*j+j*k+i*k;
	int a1,a2,a3;
	a1=i+cc[w][0];
	a2=j+cc[w][1];
	a3=k+cc[w][2];
	if(a1<0||a2<0||a3<0||a1+a2+a3<=0||s==0)
		return;
	if(w==0)
	{
		dp[a1][a2][a3]+=dp[i][j][k]*(i*k)/s;
	}
	else if(w==1)
	{
		dp[a1][a2][a3]+=dp[i][j][k]*(i*j)/s;
	}
	else
	{
		dp[a1][a2][a3]+=dp[i][j][k]*(j*k)/s;
	}
}

int main()
{
	memset(dp,0,sizeof(dp));
	scanf("%d%d%d",&a,&b,&c);
	dp[a][b][c]=1;
	double ans1=0,ans2=0,ans3=0;
	for(int i=a;i>=0;i--)
	{
		for(int j=b;j>=0;j--)
		{
			for(int w=c;w>=0;w--)
			{
				
				for(int q=0;q<3;q++)
				{
					getdp(i,j,w,q);
				}
			}
		}
	}
	for(int i=1;i<=a;i++)
		ans1+=dp[i][0][0];
	for(int i=1;i<=b;i++)
		ans2+=dp[0][i][0];
	for(int i=1;i<=c;i++)
		ans3+=dp[0][0][i];
	printf("%.10lf %.10lf %.10lf\n",ans1,ans2,ans3);
	return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章