【概率】BZOJ 3450:Tyvj1952 Easy
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了
Input
第一行一个整数n,表示点击的个数
接下来一个字符串,每个字符都是ox?中的一个
Output
一行一个浮点数表示答案
四舍五入到小数点后4位
如果害怕精度跪建议用long double或者extended
我们先开两个数组:d[i],到i后的期望连击,f[i],到i后的期望得分
我们再考虑三种情况:1.当当前是O时:d[i]=d[i-1]+1,f[i]=f[i]+2*d[i-1]+1.(为什么是2*d[i-1]+1?)
2.当前是X:d[i]=0,f[i]=f[i-1].
3.当前是?:首先我们按一下,可能+1,可能停止连击,d[i]=(d[i-1]+1)/2,f[i]=f[i]+d[i-1]+0.5。
O(N)递推.
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 6 using namespace std; 7 8 double d[300001],f[300001]; 9 10 int main() 11 { 12 int n; 13 scanf("%d\n",&n); 14 for(int i=1;i<=n;i++) 15 { 16 char x=getchar(); 17 if(x=='x')d[i]=0,f[i]=f[i-1]; 18 else if(x=='o')f[i]=f[i-1]+2*d[i-1]+1,d[i]=d[i-1]+1; 19 else f[i]=f[i-1]+d[i-1]+0.5,d[i]=(d[i-1]+1)/2; 20 } 21 printf("%.4lf",f[n]); 22 return 0; 23 }