PassTheBuck (概率)
题目连接
题意:
进行一个游戏,有几个参与者,每个参与者在其他参与者之间有一个或多个邻居。
每场比赛开始时,随机选出一名玩家,他将获得一美元(当前的持有者)。(在这个游戏中,随机选择意味着每种可能的结果都有相同的概率。)
然后,在每一步,如果当前持有者有d个邻居,他/她在[0,d]范围内随机选择一个整数k。如果选择0,当前持有者就是赢家,持有美元。否则,持有者将把美元传递给指数为k的邻居,成为新的持有者。
游戏继续进行,直到有一方获胜。
玩家和邻居的配置可以建模为一个以玩家为顶点的图,如果对应的玩家是邻居,则两个顶点之间有一条边。例如,如果他们坐在一排,那么左邻右邻就是玩家(如果有的话)。
有q组询问,求从玩家 i 开始,玩家 j 获胜的概率。
思路:
可以由当前到达各个玩家的概率,求出下一步到达所有玩家的概率,当获胜的概率比较小时退出循环,得到答案。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define sll(a) scanf("%lld", &a) 5 #define sll2(a, b) scanf("%lld %lld", &a, &b) 6 #define int long long 7 8 const int maxn = 1e5 + 10; 9 const int mod = 1e9 + 7; 10 11 const double esp=1e-8; 12 int G[50][50],n,d[50]; 13 double solve(int u,int v) 14 { 15 double now[25],nex[25],ans=0,num=0; 16 for(int i=0;i<21;i++) now[i]=nex[i]=0.0; 17 now[u]=1; 18 while(num==0.0||num>esp) 19 { 20 ans+=num; 21 num=0.0; 22 for(int i=0;i<=n;i++)nex[i]=0; 23 for(int i=1;i<=n;i++) 24 { 25 if(now[i]>0.0) 26 for(int j=1;j<=n;j++) 27 { 28 if(G[i][j]) 29 { 30 if(i==j) 31 {if(i==v)num+=now[i]*1.0/d[i];} 32 else 33 nex[j]+=now[i]*1.0/d[i]; 34 } 35 } 36 } 37 for(int i=1;i<=n;i++) 38 now[i]=nex[i]; 39 } 40 return ans; 41 } 42 signed main() 43 { 44 int m; 45 sll2(n,m); 46 for(int i=1;i<=n;i++) 47 { 48 int x; 49 sll(x);d[i]=x+1; 50 while(x--){int a;sll(a);G[i][a]=1,G[a][i]=1;} 51 G[i][i]=1; 52 } 53 while (m--) 54 { 55 int t,u,v; 56 sll(t);sll2(u,v); 57 printf("%lld %.5f\n",t,solve(u,v)); 58 } 59 return 0; 60 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步