[JLOI2013]卡牌游戏 概率DP

Posted santiego

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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;

以上是关于[JLOI2013]卡牌游戏 概率DP的主要内容,如果未能解决你的问题,请参考以下文章

[JLOI2013]卡牌游戏

BZOJ3191JLOI2013卡牌游戏 [DP]

[JLOI2013] 卡牌游戏

[bzoj3191] [JLOI2013]卡牌游戏

DP练习

bzoj千题计划202:bzoj3191: [JLOI2013]卡牌游戏