有n个箱子,第i个箱子有pi的概率开出东西,连续i个箱子开出东西的贡献为i^m,求n个箱子总贡献的期望。
dp,dp[i]表示前i个位置的总结果。显然在i处有两种情况,开出东西和没开出东西。没开出东西就是。
而开出东西的情况,就枚举这一段的起点计算,时间复杂度。
#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;
}