【动态规划】【期望】P1365 WJMZBMR打osu! / Easy

题目描述

一个o/x序列的得分为其中每个o的极大连续子段长度的平方和,比如ooxxxxooooxxx,分数就是
2×2+4×4=4+16=20
现给定一个o/x/?序列,?代表着有12的几率是o,12的几率是x,求序列的期望得分
n3e5+5

正解:O(n)期望dp

我们假设fi代表前i个数的期望答案,这时推导时我们发现,需要用到最后一段连续o的个数,但是迫于数据范围,这个值不能直接算,也不能枚举。这个时候我们该怎样得到这样一个值呢?这道题给了我们一个全新的思路。
对于每一位p,计算1~p - 1位连续'o'个数的期望,再用期望值计算:
sp == 'x':E(p) = 0
sp == 'o':E(p) = E(p - 1) + 1
sp == '?':E(p) = (E(p1)+1)+02 (E(p - 1) + 1是'?'为'o'的收益,0是'?'为'x'的收益)
将极大段的'o'拆分可得,(p+1)2p2=2p+1,对于每一个值为'o'的位置,fp=fp1+2sp1+1,对于每一个值为'?'的位置,fp=fp1+2sp1+12
一句话概括:当前位收益E(2p + 1) = 2E(p) + 1

Code

#include<bits/stdc++.h>
using namespace std;
string s;
double f[300005];
int n;
int main()
{
	double len = 0;
	cin>>n;
	cin>>s;
	f[0] = 0;
	for(int i = 0;i < s.length();i++)
	{
		if(s[i] == 'o')
		{
			f[i + 1] = f[i] + len * 2 + 1;
			len++;
		}
		if(s[i] == 'x')
		{
			f[i + 1] = f[i];
			len = 0;
		}
		if(s[i] == '?')
		{
			f[i + 1] = f[i] + len + 0.5;
			len = (len + 1) / 2;
		}
	}
	cout<<fixed<<setprecision(4)<<f[n];
	return 0;
}
posted @   The_Last_Candy  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示