Description
Analysis
如图,可能的状态转移
我比赛是想的辣鸡dp是从后往前,f[i][j]设dp到第i列,数为j的平方和的期望
为了求f,再设辅助数组g表示和的期望
那么转移显然,时间n^2
Code
我是个バカ我将中间运算过程记录成了分数实际上直接用逆元即可
#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,b,a) for(int i=b;i>=a;i--)
using namespace std;
typedef long long ll;
const int N=2010;
const ll mo=998244353;
int n;
ll p[N];
struct frac
{
ll x,y;
frac(){x=0,y=1;}
}q,w,f[N][N],g[N][N];
ll gcd(ll x,ll y)
{
if(x%y==0) return y;
else return gcd(y,x%y);
}
frac make(ll a,ll b)
{
frac t;t.x=a,t.y=b;
return t;
}
frac add(frac a,frac b)
{
frac c;
c.y=a.y*b.y%mo,c.x=(a.x*b.y%mo+a.y*b.x%mo)%mo;
return c;
}
frac add(frac a,ll b)
{
frac c=make(b,1);
return add(a,c);
}
frac mul(frac a,frac b)
{
frac c;
c.x=a.x*b.x%mo,c.y=a.y*b.y%mo;
return c;
}
frac mul(ll k,frac b)
{
frac a=make(k,1);
return mul(a,b);
}
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b)
{
x=1,y=0;
return;
}
ll x1,y1;
exgcd(b,a%b,x1,y1);
x=y1,y=x1-a/b*y1;
}
ll ny(ll a,ll b)
{
ll x,y;
exgcd(b,mo,x,y);
x=(x%mo+mo)%mo;
return a*x%mo;
}
int main()
{
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
scanf("%d",&n);
fo(i,1,n) scanf("%lld",&p[i]);
fo(i,0,n) f[n][i].x=i*i,g[n][i].x=i,f[n][i].y=g[n][i].y=1;
fd(i,n-1,0)
{
q.x=p[i+1],q.y=100;
w.x=100-p[i+1],w.y=100;
fo(j,0,i)
{
frac x=add(g[i+1][0],j);
g[i][j]=mul(w,x);
x=add(g[i+1][j+1],j);
g[i][j]=add(g[i][j],mul(q,x));
x=add(mul(2*j,g[i+1][0]),j*j);
f[i][j]=mul(w,add(f[i+1][0],x));
x=add(mul(2*j,g[i+1][j+1]),j*j);
f[i][j]=add(f[i][j],mul(q,add(f[i+1][j+1],x)));
}
}
printf("%lld",ny(f[0][0].x,f[0][0].y));
return 0;
}

本文介绍了一种使用动态规划(DP)方法解决特定数学期望值问题的方法。通过定义状态转移方程并利用辅助数组,作者实现了O(n^2)的时间复杂度。代码中详细展示了如何计算一系列数字的平方和的期望值。
437

被折叠的 条评论
为什么被折叠?



