luogu P2059 [JLOI2013]卡牌游戏

xiaoxiao2021-02-28  35

题目传送门:https://www.luogu.org/problemnew/show/P2059

题意:

N个人坐成一圈玩游戏。一开始我们把所有玩家按顺时针从1到N编号。首先第一回合是玩家1作为庄家。每个回合庄家都会随机(即按相等的概率)从卡牌堆里选择一张卡片,假设卡片上的数字为X,则庄家首先把卡片上的数字向所有玩家展示,然后按顺时针从庄家位置数第X个人将被处决即退出游戏。然后卡片将会被放回卡牌堆里并重新洗牌。被处决的人按顺时针的下一个人将会作为下一轮的庄家。那么经过N-1轮后最后只会剩下一个人,即为本次游戏的胜者。现在你预先知道了总共有M张卡片,也知道每张卡片上的数字。现在你需要确定每个玩家胜出的概率。(不好概括,很好理解,直接copy)

思路:

概率dp。设f[i][j]表示还剩i个人时,重新编号,以1号为庄家,往后数第j个人的概率。

t为被踢出去的人,如果t>j,那么j在下一轮的编号就是j-t,因为下一轮的庄家编号为t+1;

反之,如果t<j,那么j在下一轮的编号就是,i-t+j,因为c后面有i-t个人,前面有j个人。

代码:

#include<cstdio> int n,m; int a[100]; double f[100][100];//f[i][j]表示还剩i个人时,重新编号,以1号为庄家,往后数第j个人的胜率 int main() { scanf("%d %d",&n,&m); for(int i=1;i<=m;i++) scanf("%d",&a[i]); f[1][1]=1.0; for(int i=2;i<=n;i++)//枚举还剩i个人 for(int j=1;j<=i;j++)//枚举第j个人 { for(int k=1;k<=m;k++)//枚举第k张卡牌 { int t=!(a[k]%i)?i:(a[k]%i);//表示被淘汰的人 if(t>j) f[i][j]+=f[i-1][i-t+j]/(double)(m); if(t<j) f[i][j]+=f[i-1][j-t]/(double)(m); } } for(int i=1;i<=n;i++) printf("%.2lf%% ",f[n][i]*100.0); } N个人坐成一圈玩游戏。一开始我们把所有玩家按顺时针从1到N编号。首先第一回合是玩家1作为庄家。每个回合庄家都会随机(即按相等的概率)从卡牌堆里选择一张卡片,假设卡片上的数字为X,则庄家首先把卡片上的数字向所有玩家展示,然后按顺时针从庄家位置数第X个人将被处决即退出游戏。然后卡片将会被放回卡牌堆里并重新洗牌。被处决的人按顺时针的下一个人将会作为下一轮的庄家。那么经过N-1轮后最后只会剩下一个人,即为本次游戏的胜者。现在你预先知道了总共有M张卡片,也知道每张卡片上的数字。现在你需要确定每个玩家胜出的概率。
转载请注明原文地址: https://www.6miu.com/read-2620903.html

最新回复(0)