zoukankan      html  css  js  c++  java
  • [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.
  • 相关阅读:
    【Leetcode】【Easy】Remove Duplicates from Sorted List
    【Leetcode】【Easy】Pascal's Triangle II
    【Leetcode】【Easy】Pascal's Triangle
    【Leetcode】【Easy】Binary Tree Level Order Traversal II
    【Leetcode】【Easy】Binary Tree Level Order Traversal
    【Leetcode】【Easy】Maximum Depth of Binary Tree
    【Leetcode】【Easy】Minimum Depth of Binary Tree
    【Leetcode】【Easy】Balanced Binary Tree
    【Leetcode】【Easy】Symmetric Tree
    如何使用Action.Invoke()触发一个Storyboard
  • 原文地址:https://www.cnblogs.com/philchieh/p/7910319.html
Copyright © 2011-2022 走看看