http://www.lydsy.com/JudgeOnline/problem.php?id=3450
Description
某一天WJMZBMR在打osu~~~但是他太弱逼了,有些地方完全靠運氣:(
我們來簡化一下這個遊戲的規則
有n次點擊要做,成功了就是o,失敗了就是x,分數是按comb計算的,連續a個comb就有a*a分,comb就是極大的連續o。
比如ooxxxxooooxxx,分數就是2*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了
期望基本不會。呵呵。
哎。這題坑啊。
考慮每個位置對答案的貢獻是多少。
若前面串的長度是len
若這個地方是o 那他對答案的貢獻就是(len+1)^2-len^2=2*len+1,現在的len長就變成len+1了。
若這個地方是x,那他對答案的貢獻是0,len長變成0.
若是?,那分情況討論:
有0.5的概率是o,對答案的貢獻是2*len+1, len=len+1
有0.5的概率是x,對答案的貢獻是0,len=0
所以?對答案的貢獻是0.5*(2*len+1)+0.5*0, len=0.5*(len+1)+0.5*0
然後掃一遍記錄一下之前的len長度。O(n)
其實不要把期望看成期望,就看成一般的長度就行了,,(單位是一樣的嘛) 想的太複雜反而更噁心。
#include <cstdio>
char c[300001];int i,n;double x,len;
int main(){
scanf("%d\n%s",&n,c+1);
for (i=1;i<=n;++i){
if (c[i]=='o') x+=2*len+++1; else
if (c[i]=='x') len=0; else
if (c[i]=='?') x+=len+0.5,len=len/2+0.5;
}
printf("%.4f\n",x);
}