一道需要推公式的简单期望dp题。
设f[i]:到第i位为止的期望长度
g[i]:第i位结尾的连续o段的期望长度
#include <bits/stdc++.h>
using namespace std;
const int N=3e5+5;
int n;
double f[N],g[N];
char str[N];
int main(){
scanf("%d",&n);
scanf("%s",str+1);
for (register int i=1; i<=n; ++i)
{
if (str[i]=='o') f[i]=f[i-1]+2*g[i-1]+1,g[i]=g[i-1]+1;
//f[i]=f[i-1]+(g[i-1]+1)^2-g[i-1]^2=f[i-1]+2*g[i-1]+1
if (str[i]=='x') f[i]=f[i-1],g[i]=0;
if (str[i]=='?') f[i]=f[i-1]+g[i-1]+0.5,g[i]=(g[i-1]+1)/2;
//f[i]=f[i-1]+{[(g[i-1]+1)^2-g[i-1]^2]+0}/2=f[i-1]+g[i-1]+0.5
//g[i]=[(g[i-1]+1)+0]/2=(g[i-1]+1)/2
}
printf("%.4f\n",f[n]);
//一个小秘密:对于double来说,输出的时候可以输出.f
//但是如果是long double,必须输出.Lf
return 0;
}