CF1866M Mighty Rock Tower 题解
概率 DP 好题。
CF1866M 题解
题意简述
叠石头,叠完第
思路引导
按照常理,我们设的状态应该是
从第
其中,第一种情况的期望就是
第二种情况,考虑坍塌到第
第三种情况的概率是
我们直接对这三种情况的期望线性相加,即:
解得
这就是状态转移方程了。
然而,如果直接按照这个方程来打的话,时间复杂度为
由于
总复杂度为
实现
- 读入
- 预处理出
p_i 。 - 动态规划计算答案。
对于 DP 中的每一轮循环(每一个
- 计算
f_i 。 - 统计进答案。
- 处理出前缀和。
代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int MOD=998244353;
int n,p[200001],inv[1001],f[200001],s[1001];
int qpow(int x,int y) {
int res=1;
for(; y; y>>=1) {
if(y&1)res=(res*x)%MOD;
x=(x*x)%MOD;
}
return res;
}
signed main() {
cin>>n;
for(int i=1; i<=n; ++i)scanf("%lld",p+i);
int tmp=qpow(100,MOD-2);
for(int i=0; i<=100; ++i)inv[i]=i*tmp%MOD;//inv即p_i
int ans=0;
for(int i=1; i<=n; ++i) {
f[i]=(1+s[p[i]])%MOD*qpow((1+MOD-inv[p[i]])%MOD,MOD-2)%MOD;
ans=(ans+f[i])%MOD;
for(int j=0; j<=100; ++j)
s[j]=(inv[j]*s[j]%MOD+inv[j]*inv[j]%MOD*f[i]%MOD)%MOD;//s[j]是p=j的前缀和
}
cout<<ans;
}