[JLOI2013]卡牌游戏 概率DP

[JLOI2013]卡牌游戏 概率DP

题面

\(dfs\)复杂度爆炸,考虑DP。发现决策时,我们只用关心当前玩家是从庄家数第几个玩家与当前抽到的牌是啥。于是设计状态\(f[i][j]\)表示有\(i\)个人时,从庄家数第\(j\)个人的胜率。又因为此时终态确定\(f[1][1]=1\)(只有一个人时那个人胜率为100%),所以倒推回去。

转移时,枚举抽到的牌,算出从庄家数第\(t\)个会出局,那么下一局庄家就是第\(t+1\)个,当前局第\(j\)个就是下一局的第\(j-t(t< j)\)或\(i-t+j(t> j)\)个,状态于是就从\(i\)转移到了\(i-1\)

if(t>j) f[i][j]+=f[i-1][i-t+j]/m;
else if(t<j) f[i][j]+=f[i-1][j-t]/m;

代码:

#include <cstdio>
#define MAXN 1001
using namespace std;
double f[MAXN][MAXN];
int a[MAXN];
int n,m;
int main(){
    scanf("%d %d", &n, &m);
    for(int i=1;i<=m;++i) scanf("%d", &a[i]);
    f[1][1]=1;
    for(int i=2;i<=n;++i)
        for(int j=1;j<=i;++j)
            for(int k=1;k<=m;++k){
                int t=((a[k]%i==0)?i:(a[k]%i));
                if(t>j) f[i][j]+=f[i-1][i-t+j]/m;
                else if(t<j) f[i][j]+=f[i-1][j-t]/m;
            }
    for(int i=1;i<=n;++i) printf("%.2f%% ", f[n][i]*100);
    return 0;
}

原文地址:https://www.cnblogs.com/santiego/p/11437925.html

时间: 2024-08-06 08:22:23

[JLOI2013]卡牌游戏 概率DP的相关文章

bzoj 3191 [JLOI2013]卡牌游戏 概率dp

题面 题目传送门 解法 设\(f_{i,j}\)表示总共\(i\)个人,第\(j\)个人最终获胜的概率 枚举当前选择的是哪一张卡,那么就知道下一轮被淘汰的是谁了,假设是\(x\) 显然,下一轮的庄家就是\(x\)的下一个人 如果\(x=j\),那么可以不用管这种情况 如果\(x>j\),那么\(j\)在下一轮的编号为\(i-x+j\),否则为\(j-x\) 对应的两种情况转移一下即可 时间复杂度:\(O(n^2m)\) 代码 #include <bits/stdc++.h> #defin

Luogu2059 卡牌游戏-概率DP

蒟蒻的第一道概率DP.. 先讲一下我最开始yy的一个算法吧: 我们设f[i][j]表示当前进行了i轮,第j个人坐庄的概率是多少. 为什么这么想呢,因为进行了到第n轮后最后一个人必然是庄,同时这就是它的获胜的概率是吧. 可以发现转移也是很好想的.f[i][j]=f[i-1][last]/m . 但是 嗯嗯,last怎么求,好像求不出啊..所以就挂了??唉.. 但是这也是很有启发性的, 我们发现这样搞不出的原因是:它的淘汰的是围绕着庄转一定步数后的数. 而我们无法维护哪些已经被淘汰,所以我们无法继续

【BZOJ3191】【JLOI2013】卡牌游戏 概率DP

#include <stdio.h> int main() { puts("转载请注明出处谢谢"); puts("http://blog.csdn.net/vmurder/article/details/43445237"); } 题解: f[i][j]表示剩i个人时,最后要第j(相对庄家)个活下来的概率. 然后乱搞 代码: #include <cmath> #include <cstdio> #include <cstri

P2059 [JLOI2013]卡牌游戏

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

[JLOI2013]卡牌游戏

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

[bzoj3191] [JLOI2013]卡牌游戏

概率DP. 首先由题解可得>_<,胜出概率只与剩余人数.与庄家的相对位置有关. 所以设f[i][j]表示剩下i个人,从庄家开始第j个人的胜利概率... 根据卡牌一通乱搞即可... 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #define d float 6 using namespace std; 7 int a[52],

bzoj 3191: [JLOI2013]卡牌游戏

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

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

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

卡牌游戏

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