洛谷P1365

WJMZBMR打osu! / Easy

题目背景

原 维护队列 参见 P1903

题目描述

某一天WJMZBMR在打osu~~~但是他太弱逼了,有些地方完全靠运气:(

我们来简化一下这个游戏的规则

n 次点击要做,成功了就是 o,失败了就是 x,分数是按 combo 计算的,连续 a 个 combo 就有 a×a 分,combo 就是极大的连续 o

比如ooxxxxooooxxx,分数就是 2×2+4×4=4+16=20

Sevenkplus 闲的慌就看他打了一盘,有些地方跟运气无关要么是 o 要么是 x,有些地方 o 或者 x 各有 50% 的可能性,用 ? 号来表示。

比如 oo?xx 就是一个可能的输入。
那么 WJMZBMR 这场 osu 的期望得分是多少呢?

比如 oo?xx 的话,?o 的话就是 oooxx9),是x的话就是 ooxxx4),期望自然就是 (4+9)/2=6.5 了。

输入格式

第一行一个整数 nn3×105),表示点击的个数

接下来一个字符串,每个字符都是 ox? 中的一个

输出格式

一行一个浮点数表示答案

四舍五入到小数点后 4

如果害怕精度跪建议用 long double 或者 extended。

样例 #1

样例输入 #1

4
????

样例输出 #1

4.1250

思路

此题也是概率期望dp比较经典的题目,

主要要注意递推方程的写法
而且要明确期望的数学公式

之前我出错主要是因为以为能从长度的期望递推到答案的期望
显然是错误的想法

对于期望的递推要注意每种情况对它的贡献度,并且概率和为1

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 3e5 + 5;
long double dp[2];
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    string s;
    cin >> s;
    if(s[0] == '?'){
        dp[0] = 0.5;
        dp[1] = 0.5;
    }
    else if(s[0] == 'x'){
        dp[0] = 0;
        dp[1] = 0;
    }
    else if(s[0] == 'o'){
        dp[0] = 1;
        dp[1] = 1;
    }
    for(int i = 0;i < n - 1; i++){
        if(s[i+1] == 'x'){
            dp[0] = 0;
        }
        else if(s[i+1] == 'o'){
            long double p = dp[0];
            dp[0] += 1;
            dp[1] += 2*p+1;
        }
        else if(s[i+1] == '?'){
            long double p = dp[0];
            dp[0] = (dp[0] + 1) / 2;
            dp[1] += p + 0.5;
        }
        // cout << dp[1] << " " << dp[0] << endl;
    }
    cout << fixed << setprecision(4) << dp[1] << endl;
    return 0;
}
// 0.5 0.5
// 1.5 0.75
// 2.75 0.875
// 4.125 0.9375

posted @   Sun-Wind  阅读(144)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示