牛客多校第九场 E - Music Game (DP)

题目链接

有n个箱子,第i个箱子有pi的概率开出东西,连续i个箱子开出东西的贡献为i^m,求n个箱子总贡献的期望。

dp,dp[i]表示前i个位置的总结果。显然在i处有两种情况,开出东西和没开出东西。没开出东西就是dp[i-1]*(1-p_{i})

而开出东西的情况,就枚举这一段的起点计算,时间复杂度O(n^{2})

dp[i]=dp[i-1]*(1-p_{i})+\sum_{j=1}^{i}[((i-j+1)^{m}+dp[j-2])*(1-p_{j-1})*\prod_{k=j}^{i}p_{k}]

#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;

const int maxn = 1005;
const ll mod = 1e9 + 7;

int n, m;
ll p[maxn], dp[maxn];
ll mul[maxn][maxn], inv;

ll qpow(ll a, ll x)
{
    ll res = 1;
    while(x)
    {
        if(x & 1) res = (res*a) % mod;
        a = (a*a) % mod;
        x >>= 1;
    }
    return res;
}

int main()
{
    scanf("%d%d", &n, &m);
    inv = qpow(100, mod - 2);
    for(int i = 1;i <= n;i++) scanf("%lld", &p[i]);
    for(int i = 1;i <= n;i++) mul[i][i] = (p[i]*inv) % mod;
    for(int i = 1;i <= n;i++)
    {
        for(int j = i + 1;j <= n;j++)
            mul[i][j] = (mul[i][j-1]*p[j]%mod*inv)%mod;
    }
    memset(dp, 0, sizeof(dp));
    for(int i = 1;i <= n;i++)
    {
        dp[i] = (dp[i-1]*(100 - p[i])%mod*inv) % mod;
        for(int j = 1;j <= i;j++)
        {
            ll tmp = (qpow(i-j+1, m) + dp[j-2]) % mod;
            dp[i] = (dp[i] + tmp*mul[j][i]%mod*(100-p[j-1])%mod*inv%mod) % mod;
        }
    }
    printf("%lld\n", dp[n]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/NPU_SXY/article/details/83244601
今日推荐