cychester

Luogu 2059 [JLOI2013]卡牌游戏 - 概率DP

Solution

设状态 $F[i][j] $为 还剩余 $i$ 个人时, 第 $j$ 个人 的胜率。

边界: $F[1][1] = 1$(只剩下一个人了)。

这样设置状态就能使 $i-1$ 个人的答案 转移到 $i$ 个人的答案上。

最后输出 $F[N][i]$ 。

 

状态转移: 

1 int tmp = (a[k] - 1) % i + 1;
2 if (tmp == j)
3 continue;                
4 tmp = j - tmp;
5 tmp = (tmp % i + i) % i;
6 f[i][j] += 1.0 / m * f[i - 1][tmp];

 

Code

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define rd read()
 5 #define db double
 6 using namespace std;
 7 
 8 const int N = 55;
 9 
10 int n, m, a[N];
11 
12 db f[N][N];
13 
14 int read() {
15     int X = 0, p = 1; char c = getchar();
16     for (; c > '9' || c < '0'; c = getchar())
17         if (c == '-') p = -1;
18     for (; c >= '0' && c <= '9'; c = getchar())
19         X = X * 10 + c - '0';
20     return X * p;
21 }
22 
23 int main()
24 {
25     n = rd; m = rd;
26     for (int i = 1; i <= m; ++i)
27         a[i] = rd;
28     f[1][1] = 1;
29     for (int i = 2; i <= n; ++i)
30         for (int j = 1; j <= i; ++j)
31             for (int k = 1; k <= m; ++k) {
32                 int tmp = (a[k] - 1) % i + 1;
33                 if (tmp == j)
34                     continue;
35                 tmp = j - tmp;
36                 tmp = (tmp % i + i) % i;
37                 f[i][j] += 1.0 / m * f[i - 1][tmp];
38             }
39     printf("%.2lf%%", f[n][1] * 100);
40     for (int i = 2; i <= n; ++i)
41         printf(" %.2lf%%", f[n][i] * 100);
42     putchar('\n');
43 }
View Code

 

posted on 2018-09-29 13:59  cychester  阅读(169)  评论(0编辑  收藏  举报

导航