牛客——小红又战小紫(概率dp和逆元)

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网

小红上次输给了小紫,表示不服,于是又约来小紫来玩一个游戏。
这次是取石子游戏:共有nnn堆石子,两人轮流使用以下两种技能中的一种进行取石子:
1. 随机选择某一堆石子,取走其中的一颗石子。
2. 每一堆石子各取走一颗石子。

小红先手,谁先取完所有的石子谁获胜。两人都希望自己的获胜概率尽可能高,假设两人都绝顶聪明,请你计算小红最终获胜的概率。

牛客——小红又战小紫(概率dp和逆元)_第1张图片

 牛客——小红又战小紫(概率dp和逆元)_第2张图片

#include 
using namespace std;

const int N = 1010, mod = 1e9 + 7;
int n;
int c[3]; //记录石子数为1的石子堆数和石子数为2的石子堆数
int f[N];

int qmi(int x, int k) //快速幂求逆元
{
    int res = 1;
    while (k) {
        if (k & 1)
            res = (long long)res * x % mod;
        x = (long long)x * x % mod;
        k >>= 1;
    }
    return res;
}

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++) {
        int x;
        cin >> x;
        c[x]++;
    }

    //dp处理过程
    f[0] = 1;
    for (int i = 0; i <= n; i++) {
        for (int j = 1; j <= i; j++) {
            //题目要求输出的是和逆元有关,这里把除法写为逆元
            f[j] = ((long long)(i - j) * qmi(i, mod - 2) % mod * ((1 - f[j] + mod) % mod) % mod +
                    (long long)j * qmi(i, mod - 2) % mod * ((1 - f[j - 1] + mod) % mod) % mod) %
                   mod;
        }
    }
    //输出答案
    cout << f[c[2]] << endl;
    return 0;
}

题解见:牛客周赛 Round 29 F.小红又战小紫【概率dp】_小红上次输给了小紫,表示不服,于是又约来小紫来玩一个游戏。这次是取石子游戏:共-CSDN博客

逆元见:求逆元的三种方法-CSDN博客

你可能感兴趣的:(算法,概率dp,逆元)