洛谷 P2059 [JLOI2013]卡牌游戏(概率dp)

题面

洛谷

题解

\(f[i][j]\)表示有i个人参与游戏,从庄家(即1)数j个人获胜的概率是多少
\(f[1][1] = 1\)
这样就可以不用讨论淘汰了哪些人和顺序

枚举选庄家选那张牌, 枚举下一次的庄家
可以得到这次的庄家

然后转移即可

Code

#include<bits/stdc++.h>

#define LL long long
#define RG register

using namespace std;
template<class T> inline void read(T &x) {
    x = 0; RG char c = getchar(); bool f = 0;
    while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') c = getchar(), f = 1;
    while (c >= '0' && c <= '9') x = x*10+c-48, c = getchar();
    x = f ? -x : x;
    return ;
}
template<class T> inline void write(T x) {
    if (!x) {putchar(48);return ;}
    if (x < 0) x = -x, putchar('-');
    int len = -1, z[20]; while (x > 0) z[++len] = x%10, x /= 10;
    for (RG int i = len; i >= 0; i--) putchar(z[i]+48);return ;
}

const int N = 55;
int a[N];
double f[N][N];

int main() {
    //freopen(".in", "r", stdin);
    //freopen(".out", "w", stdout);
    int n, m;
    read(n); read(m);
    for (int i = 1; i <= m; i++) read(a[i]);
    f[1][1] = 100;
    for (int i = 2; i <= n; i++)
        for (int j = 1; j <= m; j++) {
            int p = a[j]%i == 0 ? i : a[j]%i;
            for (int k = 1; k < i; k++) {
                if (++p > i) p = 1;
                f[i][p] += f[i-1][k]/m;
            }
        }
    for (int i = 1; i <= n; i++)
        printf("%.2lf%% ", f[n][i]);
    return 0;
}


posted @ 2019-01-04 10:11  zzy2005  阅读(150)  评论(0编辑  收藏  举报