codeforces #301 D

来源:互联网 发布:淘宝客服退款中心 编辑:程序博客网 时间:2024/06/01 08:06

传送门在这里
题意:有a、b、c三种人,其中a克b(a和b同时出现a存活b消失),b克c,c克a,初始时abc分别有x,y,z个,每次随机出两个人(可能相同种也可能不同),经过无限次之后求每种人最后存活的概率。

思路:裸的概率dp。比较通俗的想法是设dp[i][j][k]表示剩余的人中有i个a,j个b,k个c的概率,并且初始时dp[x][y][z]=1,最后只要算出sum(dp[i][0][0])就是a存活的概率。然而麻烦的是这样需要处理出来的两个人是同一种人的情况。

换一种思路,设dp[i][j][k][0]表示剩余i个a,j个b,k个c时最后a存活的概率。那么dp[i][0][0][0]=1,而dp[x][y][z][0]就是对应的a存活的概率。


</pre><pre name="code" class="cpp">#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;}



0 0
原创粉丝点击