[BZOJ 3191][JLOI 2013]卡牌游戏

觉得这题很有必要讲一下!

现在发现在做概率题,基本是向 dp 和 马尔可夫链 靠齐

但是这一题真是把我坑了,因为状态太多,马式链什么的直接死了

我一开始的想法就是用 f[i][j] 表示剩余 i 个人,现由 j 坐庄

恩~ dp 方程还是老好想的嘛~

wait! wait!! wait!!! 这尼马有后效性啊!有后效性啊!!

然后想了半天毫无进展,一看题解……

哎呦我 c

其实那个方程几乎对了,但!是!有后效性就要用重标号的方法去掉!

怎么算去了呢?

其实……谁是谁更本不重要!

如果我们对每个人 i 都重标号为 0 ,列一次方程,那么每次都只算第 0 个人 (变为 0~n-1 个人) 存活的概率 即 f[1][0] 即可

所有方程的区别只在边界条件不同而已,标号什么的完全不用管,也就没有后效性了!

然后我们只要保证 0 不 over 即可,其他的都可以不用管了

若这一轮的标号是 0~i , 然后第 j 个人 over 的话

新标号为 0~i-1, 但是这里的 j~i-1 其实是原来的 j+1~i

但是我们不用去管标号变了的问题,因为本质上是一样的

f[i][(j+a[k]-1)%(i+1)]+=f[i+1][j]/M

这么写就可以了,但是还有个问题:

0 是不能被删的我们注意到在 f[i+1] -> f[i] 时

f[i][0] 其实是 0 被删去后 1 变为 0 坐庄的概率

但 0 存活到了最后,这是无法取的(事实上若 0 活到了最后,1 就不可能坐庄)

那么 f[i][0] 其实是什么呢?

f[i][i]!

因为这是一个环,在剩余 i+1 个人时,删掉了第 i 个人,在坐庄时当然由第 0 人来,这时所有人都没有被重标号

 1 #include <cstdio>
 2 #include <cstring>
 3 const int sizeOfPlayer=55;
 4 const int sizeOfCard=55;
 5
 6 inline int getint();
 7
 8 int N, M;
 9 int a[sizeOfCard];
10 double f[sizeOfPlayer][sizeOfCard];
11
12 int main()
13 {
14     N=getint(), M=getint();
15     for (int i=0;i<M;i++)
16         a[i]=getint();
17
18     for (int p=0;p<N;p++)
19     {
20         memset(f, 0, sizeof(f));
21         f[N][(N-p)%N]=1.0;
22         for (int i=N-1;i;i--)
23         {
24             for (int j=0;j<=i;j++)
25                 for (int k=0;k<M;k++)
26                     f[i][(j+a[k]-1)%(i+1)]+=f[i+1][j]/M;
27             f[i][0]=f[i][i];
28         }
29
30         if (p) putchar(‘ ‘);
31         printf("%.2lf%%", f[1][0]*100);
32     }
33
34     putchar(‘\n‘);
35
36     return 0;
37 }
38
39 inline int getint()
40 {
41     register int num=0;
42     register char ch;
43     do ch=getchar(); while (ch<‘0‘ || ch>‘9‘);
44     do num=num*10+ch-‘0‘, ch=getchar(); while (ch>=‘0‘ && ch<=‘9‘);
45     return num;
46 }

说的不清楚还请见谅

时间: 2024-11-05 19:28:58

[BZOJ 3191][JLOI 2013]卡牌游戏的相关文章

JLOI 2013 卡牌游戏

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

卡牌游戏

卡牌游戏 个人信息:就读于燕大本科软件工程专业 目前大三; 本人博客:google搜索"cqs_2012"即可; 个人爱好:酷爱数据结构和算法,希望将来从事算法工作为人民作出自己的贡献; 编程语言:C++ 和 java ; 编程坏境:Windows 7 专业版 x64; 编程工具:vs2008; 制图工具:office 2010 powerpoint; 硬件信息:7G-3 笔记本; 真言 敢于承认不足,敢于去接触和学习,同时又沉稳而镇静 题目 百练 1003 How far can y

计蒜客 16877 卡牌游戏

题目链接:https://nanti.jisuanke.com/t/16877 题目大意:桌子上有N堆牌,每堆牌有Si张,每张牌上有个数.小明和小红玩游戏,小红女士优先,每次从任意一个牌堆顶部取出一张,小明长得丑,每次从任意一个牌堆底部取一张.假设他俩都按照最优的方式取牌,那么谁最后得到的所有牌的数字的和大. 解题思路:首先我们考虑牌个数为偶数的几堆,那么你会发现,无论小红选哪儿个,小明只要跟着她选对应牌堆底部的,那么他俩总会各选顶部或底部一半牌,而且无论谁先手都是一样,显然这样也是最优的(我不

TCG卡牌游戏研究:《炉石战记:魔兽英雄传》所做的改变

转自:http://www.gameres.com/665306.html TCG演进史 说到卡牌游戏,大家会联想到什么呢? 是历史悠久的扑克牌.风靡全球的<MTG 魔法风云会>与<游戏王>.结合数位与现实的<三国志大战>.或是在手机上掀起收集热潮的<龙族拼图>和<百万亚瑟王>? 卡牌游戏这个统称,其内容可以跟各式各样的玩法结合,而暴风雪新推出的<炉石战记>(以下简称炉石)所选择的玩法,是让玩家自行组牌.进行对战的「集换式卡牌游戏」(

【BZOJ3191】【JLOI2013】卡牌游戏 [DP]

卡牌游戏 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description N个人坐成一圈玩游戏.一开始我们把所有玩家按顺时针从1到N编号.首先第一回合是玩家1作为庄家.每个回合庄家都会随机(即按相等的概率)从卡牌堆里选择一张卡片,假设卡片上的数字为X,则庄家首先把卡片上的数字向所有玩家展示,然后按顺时针从庄家位置数第X个人将被处决即退出游戏.然后卡片将会被放回卡牌堆里并重新洗牌.被处决的人按顺时针的下一个

菜鸟教程 | egret EUI卡牌游戏制作

写在前面 随着越来越多的新人开始接触白鹭引擎,创作属于自己的游戏.考虑到初学者会遇到的一些实际操作问题,我们近期整理推出<菜鸟教程>系列的文档,以便更好的让这些开打着们快速上手,Egret大神们可以忽略此类内容.本文作者是我们技术支持部门的同事"熊猫少女".看文的小伙伴如果有问题可以来白鹭官方论坛与之交流. EUI是一套基于Egret核心显示列表的UI扩展库,它封装了大量的常用UI组件,能够满足大部分的交互界面需求,即使更加复杂的组件需求,您也可以基于EUI已有组件进行组合

[JLOI2013]卡牌游戏 概率DP

[JLOI2013]卡牌游戏 概率DP 题面 \(dfs\)复杂度爆炸,考虑DP.发现决策时,我们只用关心当前玩家是从庄家数第几个玩家与当前抽到的牌是啥.于是设计状态\(f[i][j]\)表示有\(i\)个人时,从庄家数第\(j\)个人的胜率.又因为此时终态确定\(f[1][1]=1\)(只有一个人时那个人胜率为100%),所以倒推回去. 转移时,枚举抽到的牌,算出从庄家数第\(t\)个会出局,那么下一局庄家就是第\(t+1\)个,当前局第\(j\)个就是下一局的第\(j-t(t< j)\)或\

JAVA面向对象编程课程设计——UNO卡牌游戏

一.团队介绍 团队名称:吉祥三宝 成员名称 任务分配 个人博客连接 赖慧颖(组长) 嘤 UNO卡牌游戏-个人博客 黄雅静 嘤 UNO卡牌游戏-个人博客 杨鸿漾 嘤 UNO卡牌游戏-个人博客 二.项目Git地址 UNO卡牌游戏 三.项目git提交记录截图 四.前期调查 五.项目功能架构图.主要功能流程图 六.面向对象设计包图.类图 七.项目运行截图或屏幕录制 八.项目关键代码 九.项目代码扫描结果及改正 十.项目总结 原文地址:https://www.cnblogs.com/yhy949/p/12

bzoj 3191: [JLOI2013]卡牌游戏

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