题目链接
- 期望DP做法:
- 建立正确的OI直觉:\(x^2\)的期望可以通过\(x\)的期望递推得出,\({(x+1)}^{2}=x^2+2x+1\)
- 推式子的时候可以省去括号
- 生成函数做法:
- 注意到取出的数一定是单调不减的(除了最后一个数),为了让数列变美观,我们考虑怎样拿掉最后一个数。直接拿掉是不美的,我们考虑前缀和转化:\(P(len>i)x^i\),于是数列的每一项可以通过生成函数自动生成
- 我们的目标就是:\((P(len>i)-P(len>i+1)) (i+1)^2\)
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int mod=998244353;
long long sum,w[105],p[105],f[105],F[105];
int test(int p,int q)
{
return 1ll*p*power(q,998244351)%mod;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>w[i];
sum+=w[i];
}
for(int i=1;i<=n;i++)
{
p[i]=w[i]*power(sum,998244351)%mod;
}
for(int i=n;i>=1;i--)
{
sum=0;
for(int j=i+1;j<=n;j++)
{
sum=sum+p[j]*(f[j]+1)%mod;
}
for(int j=1;j<i;j++)
{
sum=sum+p[j];
}
sum=(sum+p[i])%mod;
f[i]=sum*power(1-p[i],998244351)%mod;
}
for(int i=n;i>=1;i--)
{
sum=0;
for(int j=i+1;j<=n;j++)
{
sum=sum+p[j]*(F[j]+2*f[j]+1)%mod;
}
for(int j=1;j<i;j++)
{
sum=sum+p[j];
}
sum=(sum+p[i]*(2*f[i]+1)%mod)%mod;
F[i]=sum*power(1-p[i],998244351)%mod;
}
cout<<(F[1]+mod)%mod<<endl;
return 0;
}
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int mod=998244353;
long long sum,mul,w[105],p[105];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>w[i];
sum+=w[i];
}
for(int i=1;i<=n;i++)
{
p[i]=w[i]*power(sum,998244351)%mod;
}
mul=1;
for(int i=1;i<=n;i++)
{
mul=mul*power(1-p[i],998244351)%mod;
}
sum=mul;
for(int i=1;i<=n;i++)
{
sum=sum+mul*p[i]%mod*power(1-p[i],998244351)%mod*2%mod;
}
sum%=mod;
cout<<(sum+mod)%mod<<endl;
return 0;
}