码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces #301 D

时间:2015-05-07 12:35:01      阅读:114      评论:0      收藏:0      [点我收藏+]

标签:

<p>传送门在<a target=_blank href="http://codeforces.com/contest/540/problem/D">这里</a></p><p>题意:有a、b、c三种人,其中a克b(a和b同时出现a存活b消失),b克c,c克a,初始时abc分别有x,y,z个,每次随机出两个人(可能相同种也可能不同),经过无限次之后求每种人最后存活的概率。</p><p>思路:裸的概率dp。比较通俗的想法是设dp[i][j][k]表示剩余的人中有i个a,j个b,k个c的概率,并且初始时dp[x][y][z]=1,最后只要算出sum(dp[i][0][0])就是a存活的概率。然而麻烦的是这样需要处理出来的两个人是同一种人的情况。</p><p>换一种思路,设dp[i][j][k][0]表示剩余i个a,j个b,k个c时最后a存活的概率。那么dp[i][0][0][0]=1,而dp[x][y][z][0]就是对应的a存活的概率。</p>
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;

double dp[105][105][105][3];
int vis[105][105][105];

void dfs(int x,int y,int z){
	//printf("%d %d %d\n",x,y,z);
	if(vis[x][y][z]){
		return;
	}
	vis[x][y][z]=1;
	double sum=1.0*x*y+1.0*x*z+1.0*y*z;
	double p0,p1,p2;
	if(x>=1) dfs(x-1,y,z);p0=1.0*x*z/sum;
	if(y>=1) dfs(x,y-1,z);p1=1.0*x*y/sum;
	if(z>=1) dfs(x,y,z-1);p2=1.0*y*z/sum;
	if(x>=1){
		dp[x][y][z][0]+=dp[x-1][y][z][0]*p0;
		dp[x][y][z][1]+=dp[x-1][y][z][1]*p0;
		dp[x][y][z][2]+=dp[x-1][y][z][2]*p0;
	}
	if(y>=1){
		dp[x][y][z][0]+=dp[x][y-1][z][0]*p1;
		dp[x][y][z][1]+=dp[x][y-1][z][1]*p1;
		dp[x][y][z][2]+=dp[x][y-1][z][2]*p1;
	}
	if(z>=1){
		dp[x][y][z][0]+=dp[x][y][z-1][0]*p2;
		dp[x][y][z][1]+=dp[x][y][z-1][1]*p2;
		dp[x][y][z][2]+=dp[x][y][z-1][2]*p2;
	}
}


int main(){
	int x,y,z;
	int i,j;
	scanf("%d%d%d",&x,&y,&z);
		memset(dp,0,sizeof(dp));
		memset(vis,0,sizeof(vis));
		for(i=0;i<=100;i++){
			vis[i][0][0]=1;vis[0][i][0]=1;vis[0][0][i]=1;
			dp[i][0][0][0]=1;
			dp[0][i][0][1]=1;
			dp[0][0][i][2]=1;
		}
		dfs(x,y,z);
		printf("%.12f\n%.12f\n%.12f\n",dp[x][y][z][0],dp[x][y][z][1],dp[x][y][z][2]);
		return 0;
}



codeforces #301 D

标签:

原文地址:http://blog.csdn.net/u011822304/article/details/45557891

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!