[BZOJ3450/TYVJ1952]Easy
Description
某一天WJMZBMR在打osu\(\sim\sim\sim\)但是他太弱逼了,有些地方完全靠运气:(
我们来简化一下这个游戏的规则
有n次点击要做,成功了就是o,失败了就是x,分数是按comb计算的,连续a个comb就有aa分,comb就是极大的连续o。
比如ooxxxxooooxxx,分数就是22+4*4=4+16=20。
Sevenkplus闲的慌就看他打了一盘,有些地方跟运气无关要么是o要么是x,有些地方o或者x各有50%的可能性,用?号来表示。
比如oo?xx就是一个可能的输入。
那么WJMZBMR这场osu的期望得分是多少呢?
比如oo?xx的话,?是o的话就是oooxx => 9,是x的话就是ooxxx => 4
期望自然就是(4+9)/2 =6.5了
Input
第一行一个整数n,表示点击的个数
接下来一个字符串,每个字符都是ox?中的一个
Output
一行一个浮点数表示答案
四舍五入到小数点后4位
如果害怕精度跪建议用long double或者extended
Sample Input
4
????
Sample Output
4.1250
HINT
n<=300000
osu很好玩的哦
WJMZBMR技术还行(雾),x基本上很少呢
考虑dp,我们设f[i]表示到第i个点的得分期望,g[i]表示到第i个点o的长度期望,转移就十分显然了
\((x+1)^2=x^2+2x+1\)
/*program from Wolfycz*/
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline char gc(){
static char buf[1000000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
inline int frd(){
int x=0,f=1; char ch=gc();
for (;ch<'0'||ch>'9';ch=gc()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=gc()) x=(x<<3)+(x<<1)+ch-'0';
return x*f;
}
inline int read(){
int x=0,f=1; char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+ch-'0';
return x*f;
}
inline void print(int x){
if (x<0) putchar('-'),x=-x;
if (x>9) print(x/10);
putchar(x%10+'0');
}
const int N=3e5;
double f[N+10],g[N+10];
char s[N+10];
int main(){
int n=read();
scanf("%s",s+1);
for (int i=1;i<=n;i++){
if (s[i]=='x') f[i]=f[i-1],g[i]=0;
if (s[i]=='o') f[i]=f[i-1]+2*g[i-1]+1,g[i]=g[i-1]+1;
if (s[i]=='?') f[i]=f[i-1]+g[i-1]+0.5,g[i]=(g[i-1]+1)/2;
}
printf("%.4lf\n",f[n]);
return 0;
}