1. 程式人生 > >bzoj 3191 [JLOI2013]卡牌遊戲 概率dp

bzoj 3191 [JLOI2013]卡牌遊戲 概率dp

遊戲 inline mat turn ble 解法 不用 轉移 rec

題面

題目傳送門

解法

\(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;
}

bzoj 3191 [JLOI2013]卡牌遊戲 概率dp