原题传送门
这是一道期望dp题
令
f
[
i
]
表
示
第
i
位
时
期
望
得
分
,
g
[
i
]
表
示
第
i
位
时
o
期
望
长
度
f[i]表示第i位时期望得分,g[i]表示第i位时o期望长度
f[i]表示第i位时期望得分,g[i]表示第i位时o期望长度
对于当前字符
s
[
i
]
s[i]
s[i],分类讨论:
- s [ i ] = ′ o ′ : g [ i ] = g [ i − 1 ] + 1 s[i]='o':g[i]=g[i-1]+1 s[i]=′o′:g[i]=g[i−1]+1, f [ i ] = g [ i ] 2 = ( g [ i − 1 ] + 1 ) 2 = g [ i − 1 ] 2 + 2 g [ i − 1 ] + 1 = f [ i − 1 ] + 2 g [ i − 1 ] + 1 f[i]=g[i]^2=(g[i-1]+1)^2=g[i-1]^2+2g[i-1]+1=f[i-1]+2g[i-1]+1 f[i]=g[i]2=(g[i−1]+1)2=g[i−1]2+2g[i−1]+1=f[i−1]+2g[i−1]+1
- s [ i ] = ′ x ′ : g [ i ] = 0 , f [ i ] = f [ i − 1 ] s[i]='x':g[i]=0,f[i]=f[i-1] s[i]=′x′:g[i]=0,f[i]=f[i−1]
- s [ i ] = ′ ? ′ ( 把 上 面 两 个 方 程 合 并 ) : g [ i ] = 0 2 + g [ i − 1 ] + 1 2 = g [ i − 1 ] + 1 2 , f [ i ] = f [ i − 1 ] 2 + f [ i − 1 ] + 2 g [ i − 1 ] + 1 2 = f [ i − 1 ] + g [ i − 1 ] + 0.5 s[i]='?'(把上面两个方程合并):g[i]=\frac{0}{2}+\frac{g[i-1]+1}{2}=\frac{g[i-1]+1}{2},f[i]=\frac{f[i-1]}{2}+\frac{f[i-1]+2g[i-1]+1}{2}=f[i-1]+g[i-1]+0.5 s[i]=′?′(把上面两个方程合并):g[i]=20+2g[i−1]+1=2g[i−1]+1,f[i]=2f[i−1]+2f[i−1]+2g[i−1]+1=f[i−1]+g[i−1]+0.5
再发现:
f
[
i
]
,
g
[
i
]
只
与
f
[
i
−
1
]
,
g
[
i
−
1
]
有
关
,
顺
手
滚
动
掉
f[i],g[i]只与f[i-1],g[i-1]有关,顺手滚动掉
f[i],g[i]只与f[i−1],g[i−1]有关,顺手滚动掉
Code:
#include <bits/stdc++.h>
using namespace std;
double f[2], g[2];
int n;
int main(){
scanf("%d", &n);
for (int i = 1; i <= n; ++i){
int p = i & 1;
char c = getchar();
for (; c != 'x' && c != 'o' && c != '?'; c = getchar());
if (c == 'o') g[p] = g[p ^ 1] + 1, f[p] = f[p ^ 1] + 2 * g[p ^ 1] + 1; else
if (c == 'x') g[p] = 0, f[p] = f[p ^ 1]; else g[p] = (g[p ^ 1] + 1) / 2, f[p] = f[p ^ 1] + g[p ^ 1] + 0.5;
}
printf("%.4f\n", f[n & 1]);
return 0;
}

博客围绕一道期望DP题展开,定义f[i]为第i位时期望得分,g[i]为第i位时o期望长度。针对当前字符s[i]的不同情况('o'、'x'、'?')进行分类讨论,得出相应的递推公式,还指出f[i]、g[i]只与f[i - 1]、g[i - 1]有关可滚动处理。
3134

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



