补充:n<=300000
分析:
比较好想的是二维的dp:
f[i][j]表示到第i位,已经连续有j个零的期望
且不说如何转移,这样的时间复杂度是O(n^2),显然GG
所以我们需要改变状态:
考虑将第二维也变成期望
f[i]表示到第i次点击的期望得分,g[i]表示到第i次点击的期望o的连续长度(这一段连续的o一定是以i为结尾)
转移的时候只要分类讨论即可(o,x,?)
tip
第一遍WA,原因竟然是读入错误
//这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std;
const int N=300010;
int n;
double f[N],g[N];
int main()
{
scanf("%d",&n);
char s[N];
scanf("%s",s+1);
for (int i=1;i<=n;i++)
{
if (s[i]=='x') f[i]=f[i-1],g[i]=0;
else if (s[i]=='o'){
f[i]=f[i-1]-g[i-1]*g[i-1];
g[i]=g[i-1]+1.0;
f[i]+=g[i]*g[i];
}
else {
g[i]=(g[i-1]+1.0)/2.0; //0.5的概率是o
f[i]=f[i-1]/2.0; //0.5的概率第i个是x
double r=f[i-1]-g[i-1]*g[i-1];
r+=(g[i-1]+1.0)*(g[i-1]+1.0); //0.5的概率第i个是o
f[i]+=r/2.0;
}
}
printf("%.4lf",f[n]);
return 0;
}