介绍:


前言:
Hello 大家好,这里是小亦,是不是想念小亦博主了呀,因为一些事情导致小亦一直没时间为大家更新文章了,现在呢也是回归了呢~那话不多说那我们今天所观看就是来自洛谷的一篇题解话不多说~
这道题的核心思路无非就是让我们利用 动态DP 递推期望得分,也就是抓住 "得分变化仅与当前连续 combo 长度所相关的",比变枚举所有发生的情况。下面也是小亦为大家的思路步骤~
#解题思路步骤:
1、明确游戏的规则与期望本质:
1.1、得分规则:有 连续 a 个 0 贡献 分, x 中断 combo ,? 是 50% o / 50% x 。
1.2、期望的本质:所有可能的情况的得分平均值。比如 00?xx 有两种情况,得分 4 和 9 ,期望值就是 ( 4 + 9 )/ 2 = 6.5 。
1.3、关键痛点: n 为最大 3e5 ,枚举所有 2 ^ 3e5 种情况完全不可能,必须得找"递推公式"进行高效计算。
2、得分增量的规律:
我们直接计算总得分的期望很难,但是我们可以拆分成 "每一步新增的得分期望",再累加所有步骤增量。
3、动态dp状态设计:
我们不需要存储完整的得分和 combo 的序列,仅需两个变量就能进行递推:
3.1、prev_len :前一步结束后,连续的 combo 的期望长度。
3.2、ans : ;累计的总期望得分。
为什么用 "期望长度" 呢。这是因为 ? 带来了不确定性所以我们无法确定 combo 的具体长度,但我们可以计算其 "期望",再用期望推导的粉增量的期望。
4、分情况进行推导递推公式:
对于每个字符( 0 / x / ? ),分别推导 prev_len 和 ans 的更新方式 :
4.1、 当前字符是 o :combo 长度必然 +1 :new_len = prev_len + 1 。得分增量的期望=
2 * prev_len + 1 。
得分增量的期望 = 2 * prev_len + 1 更新:ans += 2 * prev_len +1 prev_len = new_len
4.2、当前字符是 x ,combo 长度必然归于 0 : new_len = 0 。得分增量的期望 = 0。 更新: ans 不变化 prev_len = 0
4.3、当前字符是 未知:combo 长度期望:new_len = 0.5 * ( prev_len + 1 ) + 0.5 + 0 = ( prev_len + 1 ) / 2 。得分增量的期望: 0.5 * ( 2 * prev_len + 1 ) + 0.5 * 0 = prev_len + 0.5。
4.4、终于到最后了)更新:ans += prev_len + 0.5 prev_len = new_len 。
##复杂度:
1、时间复杂度:
。
2、空间复杂度:
。
###代码:
cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
string a;
cin >> n >> a;
long double ans = 0.0;
long double prev_len = 0.0;
for (char c : a) {
if (c == 'o') {
ans += 2 * prev_len + 1;
prev_len += 1.0;
} else if (c == 'x') {
prev_len = 0.0;
} else if (c == '?') {
ans += prev_len + 0.5;
prev_len = (prev_len + 1.0) / 2.0;
}
}
cout << fixed << setprecision(4) << ans << endl;
return 0;
}
感谢观看!!!
制作:Code.小亦
代码提供:Code.小亦
题目思路部分提供:seabird
代码部分思路提供:无
初审:Code.小亦。
终审:Code.小亦
本文章属于原创作品,禁止任何人进行转载,除合作之外!!