洛谷P1365 WJMZBMR打osu 题解

题目链接

分析:

f i f_i fi表示前 i i i位的期望分数; g i g_i gi表示从第 i i i位往前,期望有多少的连续的'o'

每一位分为三种情况转移:

1、当前位为'x':

显然有:
g i = 0 , f i = f i − 1 g_i = 0,f_i = f_{i - 1} gi=0,fi=fi1

2、当前位为'o'

稍微复杂一点,为:
g i = g i − 1 + 1 g_i = g_{i - 1} + 1 gi=gi1+1
f i = f i − 1 − g i − 1 2 + g i 2 = f i − 1 − g i − 1 2 + ( g i − 1 + 1 ) 2 = f i − 1 + 2 g i − 1 + 1 f_i = f_{i - 1} - g_{i - 1} ^ 2 +g_i ^ 2 = f_{i - 1} - g_{i - 1} ^ 2 + (g_{i - 1} + 1) ^ 2 = f_{i - 1} + 2g_{i - 1} + 1 fi=fi1gi12+gi2=fi1gi12+(gi1+1)2=fi1+2gi1+1

3 、当前位为'?':

'?'时其实就是1、2两种情况各占 50 % 50\% 50%的可能性,把1、2两种情况相加再除以 2 2 2即可:
g i = ( g i − 1 + 1 + 0 ) / 2 = 0.5 g i − 1 + 0.5 g_i = (g_{i - 1} + 1 + 0) / 2 = 0.5g_{i - 1} + 0.5 gi=(gi1+1+0)/2=0.5gi1+0.5
f i = ( f i − 1 + f i − 1 + 2 g i − 1 + 1 ) / 2 = f i − 1 + g i − 1 + 0.5 f_i = (f_{i - 1} + f_{i - 1} + 2g_{i - 1} + 1) / 2 = f_{i - 1} + g{i - 1} + 0.5 fi=(fi1+fi1+2gi1+1)/2=fi1+gi1+0.5

Code:

#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 3e5 + 50;
int n;
double f[maxn],g[maxn];
char c;
int main(){
    cin >> n;
    c = getchar();//读掉换行符
    for(int i = 1; i <= n; i ++){
        c = getchar();
        if(c == 'o') g[i] = g[i - 1] + 1,f[i] = f[i - 1] + g[i] + g[i - 1];
        else if(c == 'x') g[i] = 0,f[i] = f[i - 1];
        else g[i] = (g[i - 1] + 1) / 2,f[i] = f[i - 1] + g[i - 1] + 0.5;
    }
    printf("%.4lf",f[n]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值