• [jzoj]3468.【NOIP2013模拟联考7】OSU!(osu)


    Link

      https://jzoj.net/senior/#main/show/3468

    Description

      osu 是一款群众喜闻乐见的休闲软件。
      我们可以把osu的规则简化与改编成以下的样子: 
      一共有n次操作,每次操作只有成功与失败之分,成功对应1,失败对应0,n次操作对应为一个长度为n的01串。在这个串中连续的x个1可以贡献x^3的分数,这x个1不能被其他连续的1所包含(也就是极长的一串1,具体见样例解释)
      现在给出n,以及每个操作的成功率,请你输出期望分数,输出四舍五入后保留1位小数。

    Solution

      我疑心这是一道极好的题目,网上的题解阐述的是大概,吾大都不懂。下面是我自个儿的理解,赘述一下。。

    60分

      我们发现,如果位置是0,那么对答案没有一点贡献。

      答案是由一个或一段的1贡献的。所以,我们可以枚举连续的一段1的位置,使其满足它是相对独立的,没有与别段有交集。

    100分

      有办法可以快速处理以上的方法吗。答案使没有的。我们只能另辟途径。

      看到概率,脑子里除了DP就是暴力。

      循规蹈矩地设F[i]表示前i位的期望答案。

      当前位选0,那么答案便是f[i-1];当前位选1,那么对答案的贡献自然就多了,设这个多出来的贡献为k。

      根据上面的理解可以得到

      F[i]=f[i-1]*(1-p[i])+(f[i-1]+k)*p[i]

      整理可得

      f[i]:=f[i-1]+贡献*p[i];

      关键是贡献的如果求贡献。我们知道,每次多1,那么答案就多(x+1)3--x3=3*x2+3x+1,x显然是一个期望长度。令人蛋疼的是,期望的平方不等于平方的期望

      设g1表示一次项的期望长度,g2表示二次项的期望长度。

      g1相当于x,是期望长度,那么显然g1[i]=(g1[i-1]+1)*p[i]

      因为(x+1)2-x2=2x+1,故可得g2[i]=(g2[i-1]+2*g1[i-1]+1)*p[i];

      贡献的问题显然可得。具体见标程

    Code

      60分

    var
            now,ans:extended;
            n,i,j:longint;
            a:array[0..1000] of extended;
    begin
            assign(input,'osu.in');reset(input);
            assign(Output,'osu.out');rewrite(output);
    
            readln(n);
    
            for i:=1 to n do
                    readln(a[i]);
    
            for i:=1 to n do
            begin
                    now:=1;
                    for j:=1 to n-i+1 do
                    begin
                            now:=now*a[i+j-1];
    
                            ans:=ans+j*j*j*now*(1-a[i-1])*(1-a[i+j]);
                    end;
            end;
    
            writeln(ans:0:1);
    end.

      100分

    var
            n,i:longint;
            a,f,g1,g2:array[0..100000] of extended;
    begin
            assign(input,'osu.in');reset(input);
            assign(Output,'osu.out');rewrite(output);
    
            readln(n);
    
            for i:=1 to n do
                    readln(a[i]);
    
            for i:=1 to n do
            begin
                    g1[i]:=(g1[i-1]+1)*a[i];
                    g2[i]:=(g2[i-1]+2*g1[i-1]+1)*a[i];
                    f[i]:=f[i-1]+(3*g2[i-1]+3*g1[i-1]+1)*a[i];
            end;
    
            writeln(f[n]:0:1);
    end.
  • 相关阅读:
    C# 执行bat文件 PHP
    windows服务操作 sc批处理 PHP
    HTML 彩虹 PHP
    C# 简易日志记录类 PHP
    C# 读写INI文件 PHP
    .NET Framework PHP
    序列号备忘 PHP
    获取浏览器版本信息
    数据库中Image字段存储读取数据
    [转]装机推荐 5000元铸造最强游戏平台
  • 原文地址:https://www.cnblogs.com/philchieh/p/7910319.html
Copyright © 2020-2023  润新知