【题意】
一个岛上有三种生物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碰面,概率是 p1 = i*j / (i*j+j*k+k*i),这种情况下,B会被A吃掉,所以B的数目减少1,表现出来是dp[i][j][k]= p1*dp[i][j-1][k] (dp的3的返回值均参与计算)
B与C碰面,A与C碰面也是如此。
用全概率公式,最后的状态转移方程为 dp[i][j][k]= i*j / sum * dp[i][j-1][k] + j*k/ sum * dp[i][j][k-1] + k*i/ sum *dp[i-1][j][k]
其中sum=i*j+j*k+k*i (满足全概率公式中的 i*j/sum 、 j*k/sum 、 k*i/sum 和为1 )
#include<bits/stdc++.h> #define eps 1e-9 #define FOR(i,j,k) for(int i=j;i<=k;i++) #define MAXN 1005 #define MAXM 40005 #define INF 0x3fffffff #define PB push_back #define MP make_pair #define X first #define Y second #define lc (k<<1) #define rc ((k<<1)1) using namespace std; typedef long long LL; int i,j,k,n,m,x,y,T,ans,big,cas,num,len; bool flag; struct node { double x,y,z; node (){} node (double x,double y,double z):x(x),y(y),z(z){} }dp[105][105][105]; bool vis[105][105][105]; node dfs(int a,int b,int c) { if (vis[a][b][c]) return dp[a][b][c]; vis[a][b][c]=1; int sum=a*b+b*c+a*c; node r=node(0,0,0),s=node(0,0,0),t=node(0,0,0),rt; if (b>0) r=dfs(a,b-1,c); double p1=a*b*1.0/sum; if (c>0) s=dfs(a,b,c-1); double p2=b*c*1.0/sum; if (a>0) t=dfs(a-1,b,c); double p3=c*a*1.0/sum; rt.x=p1*r.x+p2*s.x+p3*t.x; rt.y=p1*r.y+p2*s.y+p3*t.y; rt.z=p1*r.z+p2*s.z+p3*t.z; return dp[a][b][c]=rt; } int main() { int a,b,c; scanf("%d%d%d",&a,&b,&c); memset(vis,0,sizeof(vis)); for (i=1;i<=100;i++) { vis[0][0][i]=1; dp[0][0][i].z=1; vis[0][i][0]=1; dp[0][i][0].y=1; vis[i][0][0]=1; dp[i][0][0].x=1; } node ans=dfs(a,b,c); memset(dp,-1,sizeof(dp)); printf("%.12f %.12f %.12f\n",ans.x,ans.y,ans.z); return 0; }
时间: 2024-11-09 00:02:15