原 維護隊列 參見P1903數組
某一天\(WJMZBMR\)在打\(osu~~~\)可是他太弱逼了,有些地方徹底靠運氣:(spa
咱們來簡化一下這個遊戲的規則code
有\(n\)次點擊要作,成功了就是\(`o`\),失敗了就是\(`x`\),分數是按\(combo\)計算的,連續\(a\)個\(combo\)就有\(a\times a\)分,\(combo\)就是極大的連續\(`o`\)。隊列
好比\(`ooxxxxooooxxx`\),分數就是\(2 \times 2 + 4 \times 4 = 4\) +16=20。遊戲
\(Sevenkplus\)閒的慌就看他打了一盤,有些地方跟運氣無關要麼是\(`o`\)要麼是\(`x`\),有些地方\(`o`\)或者\(`x`\)各有\(50\%\)的可能性,用\(`?`\)號來表示。字符串
好比\(`oo?xx`\)就是一個可能的輸入。 那麼\(WJMZBMR\)這場\(osu\)的指望得分是多少呢?string
好比\(`oo?xx`\)的話,\(`?`\)是\(`o`\)的話就是\(`oooxx` => 9\),是\(x\)的話就是\(`ooxxx` => 4\)io
指望天然就是\((4+9)/2 =6.5\)了class
輸入格式:im
第一行一個整數\(n\),表示點擊的個數
接下來一個字符串,每一個字符都是\(`o`,`x`,`?`\)中的一個
輸出格式:
一行一個浮點數表示答案
四捨五入到小數點後\(4\)位
若是懼怕精度跪建議用\(long double\)或者\(extended\)
輸入樣例#1:
4 ????
輸出樣例#1:
4.1250
\(osu\)很好玩的哦
\(WJMZBMR\)技術還行(霧),\(x\)基本上不多呢
思路:用dp數組表示指望值,用f數組表示到某位置時連續的o的個數。而後進行分類討論:
1.當\(s[i]\)爲\(’o’\)時,\(dp[i]=dp[i-1]+2×f[i-1]+1,f[i]=f[i-1]+1\);
由於\((x+1)^2=x^2+2 \times x + 1\)
2.當\(s[i]\)爲\(‘x’\)時,\(dp[i]=dp[i-1],f[i]=0\);
3.\(else\) 指望和的平均值就好咯,由於機率都是\(0.5\),因此都乘\(0.5\)相加就能夠了。
代碼:
#include<cstdio> #include<cstring> #define dl double #define maxn 1000007 using namespace std; int n; dl dp[maxn],f[maxn]; char s[maxn]; int main() { scanf("%d%s",&n,s+1); int len=strlen(s+1); for(int i=1;i<=len;++i) { if(s[i]=='x') dp[i]=dp[i-1],f[i]=0; else if(s[i]=='o') dp[i]=dp[i-1]+2*f[i-1]+1,f[i]=f[i-1]+1; else dp[i]=dp[i-1]+f[i-1]+0.5,f[i]=(f[i-1]+1)*0.5; } printf("%0.4lf\n",dp[len]); return 0; }