• [Luogu1365] WJMZBMR打osu! / Easy


    Description

    某一天WJMZBMR在打osu~~~但是他太弱逼了,有些地方完全靠运气:(

    我们来简化一下这个游戏的规则

    (n) 次点击要做,成功了就是o,失败了就是x,分数是按combo计算的,连续 (a) 个combo就有 (a imes a) 分,combo就是极大的连续o

    比如ooxxxxooooxxx,分数就是 (2 imes 2 + 4 imes 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(4+9)/2=6.5 了

    Input

    第一行一个整数 n ,表示点击的个数

    接下来一个字符串,每个字符都是o,x,?中的一个

    Output

    一行一个浮点数表示答案

    四舍五入到小数点后 4 位

    如果害怕精度跪建议用long double或者extended

    Hint

    (Nleq 300000)

    Solution

    显然期望 (dp) 的套路。定义两个数组 (f[i],g[i]) 分别表示到 (i) 的总得分和以 (i) 为结尾的 (combo) 长度。

    如果当前是o 根据 ((x+1)^2=x^2+2x+1)(f[i]=f[i-1]+2*g[i-1]+1),同时 (g[i]=g[i-1]+1)

    如果当前是x (f[i]=f[i-1],g[i]=0)

    如果当前是? 因为各有 (0.5) 的可能性,所以 (f[i]=0.5*(f[i-1]+2*g[i-1]+1)+0.5*f[i-1],g[i]=0.5*(g[i-1]+1)+0.5*0)

    Code

    #include<cstdio>
    #define N 300005
    #define db double
    
    int n;
    db f[N];
    db g[N];
    char ch[N];
    
    signed main(){
    	scanf("%d",&n);
    	scanf("%s",ch+1);
    	for(int i=1;i<=n;i++){
    		if(ch[i]=='o'){
    			f[i]=f[i-1]+2*g[i-1]+1;
    			g[i]=g[i-1]+1;
    		} else if(ch[i]=='x'){
    			f[i]=f[i-1];
    			g[i]=0;
    		} else{
    			g[i]=(g[i-1]+1)/2.0;
    			f[i]=0.5*f[i-1]+0.5*(f[i-1]+2*g[i-1]+1);
    		}
    	}
    	printf("%.4lf
    ",f[n]);
    	return 0;
    }
    
  • 相关阅读:
    Python学习笔记
    Python学习笔记
    不定宽高垂直居中分析
    PhoneGap安装配置
    Mongoose学习参考资料
    我的node+express小例子
    node+express+mongodb初体验
    stylie工具轻松搞定css3抛物线动画
    fis前端开发框架
    Fiddler实现手机的抓包(转载园友小坦克)
  • 原文地址:https://www.cnblogs.com/YoungNeal/p/9254361.html
Copyright © 2020-2023  润新知