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>
#define N 110
using namespace std;
int a[N];
double f[N][N];
int main() {
    int n, m; cin >> n >> m;
    for (int i = 1; i <= m; i++) cin >> 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 x = a[k] % i ? a[k] % i : i;
                if (!x) x = n;
                if (x == j) continue;
                if (x > j) f[i][j] += f[i - 1][i - x + j] / m;
                    else f[i][j] += f[i - 1][j - x] / m;
            }
    for (int i = 1; i <= n; i++)
        cout << fixed << setprecision(2) << f[n][i] * 100 << "% ";
    return 0;
}

原文地址:https://www.cnblogs.com/copperoxide/p/9476704.html

时间: 2024-08-13 00:39:16

bzoj 3191 [JLOI2013]卡牌游戏 概率dp的相关文章

[JLOI2013]卡牌游戏 概率DP

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

bzoj 3191: [JLOI2013]卡牌游戏

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

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],

【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