题目:
题解:
一眼看上去好想dfs啊,n<=30000
我们考虑递推解决问题。f(i)表示以第i个字符结尾的期望得分,g(i)表示以第i个字母结尾o连续的期望长度
分情况讨论(设L为当前连续的o长度,其实就是g[i-1]啦)
当s[i]=’x’,L=0,显然f[i]=f[i-1],g[i]=0
当s[i]=’o’,L=L+1,得分从
L2
L
2
变成
L2+2L+1
L
2
+
2
L
+
1
,比原来增加了
2L+1
2
L
+
1
,所以
g[i]=g[i−1]+1,f[i]=f[i−1]+2∗g(i−1)+1
g
[
i
]
=
g
[
i
−
1
]
+
1
,
f
[
i
]
=
f
[
i
−
1
]
+
2
∗
g
(
i
−
1
)
+
1
当s[i]=’?’,L变不变都是0.5的概率,那么
g[i]=(g[i−1]+1)/2,f[i]=f[i−1]+(2∗g(i−1)+1)/2
g
[
i
]
=
(
g
[
i
−
1
]
+
1
)
/
2
,
f
[
i
]
=
f
[
i
−
1
]
+
(
2
∗
g
(
i
−
1
)
+
1
)
/
2
代码:
#include <cstdio>
#include <cstring>
using namespace std;
const int N=300005;
int n;double f[N],g[N];char st[N];
int main()
{
scanf("%d",&n);
scanf("%s",st+1);
for (int i=1;i<=n;i++)
if (st[i]=='o') f[i]=f[i-1]+2*g[i-1]+1,g[i]=g[i-1]+1;
else if (st[i]=='x') f[i]=f[i-1],g[i]=0;
else f[i]=f[i-1]+g[i-1]+0.5,g[i]=(g[i-1]+1)/2.0;
printf("%.4lf",f[n]);
}