洛谷 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;
}