洛谷 P1365 WJMZBMR打osu! / Easy
阿新 • • 發佈:2020-10-20
洛谷 P1365 WJMZBMR打osu! / Easy
題目背景
原 維護佇列 參見P1903
題目描述
某一天WJMZBMR在打osu~~~但是他太弱逼了,有些地方完全靠運氣:(
我們來簡化一下這個遊戲的規則
有nn次點選要做,成功了就是o
,失敗了就是x
,分數是按combo計算的,連續aa個combo就有a\times aa×a分,combo就是極大的連續o
。
比如ooxxxxooooxx
x,分數就是2 \times 2 + 4 \times 4 = 4 +16=202×2+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(4+9)/2=6.5了
輸入格式
第一行一個整數n(n\le3\times10^5)n(n≤3×105),表示點選的個數
接下來一個字串,每個字元都是o
,x
,?
中的一個
輸出格式
一行一個浮點數表示答案
四捨五入到小數點後44位
如果害怕精度跪建議用long double或者extended
題解:
與P1654OSU!的思路基本一樣:
分類討論去求即可。
程式碼:
#include<cstdio> using namespace std; const int maxn=3*1e5+10; int n; char s[maxn]; double dp[maxn],f[maxn]; int main() { scanf("%d%s",&n,s+1); for(int i=1;i<=n;i++) { if(s[i]=='o') f[i]=f[i-1]+1; if(s[i]=='x') f[i]=0; if(s[i]=='?') f[i]=(f[i-1]+1)*0.5; } for(int i=1;i<=n;i++) { if(s[i]=='o') dp[i]=dp[i-1]+(2*f[i-1]+1); if(s[i]=='x') dp[i]=dp[i-1]; if(s[i]=='?') dp[i]=dp[i-1]+(2*f[i-1]+1)*0.5; } printf("%.4lf",dp[n]); return 0; }