• HNOI 2015 【亚瑟王】


    看着洛谷里那一排任务计划,瑟瑟发抖。。。。。。

    题目大意:

    你有n张牌,每一张牌有一个发动的概率和造成的伤害值,游戏一共有r轮。对于每一轮游戏,你只能发动一张牌(在之前回合发动过的牌会被跳过,不予考虑),在发动一张牌后这轮游戏结束,进入下一轮。让你求出r轮游戏后,这套牌造成伤害的希望。

    输入:t组数据,n张牌,r轮游戏,每张牌在每轮发动的概率p[i],该牌造成的伤害d[i]。

    输出:期望伤害值。

    思路分析:

    注意到期望具有线性性,所以我们可以通过求出每张牌在总共r轮游戏中会发动的概率(g[i]),然后再乘上它的伤害(d[i]),相加,就能得到答案。

    即:E=∑ni=1 g[i]*d[i]

    那么我们应该如何求出g数组呢?

    首先我们可以轻而易举地求出g[1]——g[1]=1-(1-p[1])r,其中(1-p[1])r 就是指第1张牌在r个回合中至始至终都不发动的概率。

    那么g[2]怎么求呢?

    注意到g[2]发动有2种情况:

            1、第一张牌始终不发动,第二张牌发动。那么此时有r个回合考虑到了第二张牌。

            2、第一张牌发动,第二张牌也发动。那么此时有r-1个回合考虑到了第二张牌。

    所以:p[2]=(1-p[1])r*[1-(1-p[2])r]+[1-(1-p[1])r]*[1-(1-p[2])r-1]

    发现了什么?

    貌似第i张牌发动的概率,只和前i-1牌的发动情况有关,如果前i-1张牌中有j张牌发动过了,那么第i张牌就被考虑了r-j次,发动的概率就为:(前i-1张牌,有j张发动的概率)*[1-(1-p[i])r-j]。

    所以:p[i]=∑rj=0 (前i张牌有j张牌发动的概率)*[1-(1-p[i])r-j]

    那么我们就新加一个f数组,f[i,j]就表示前i张牌,有j张牌被发动过的概率。

    f[i,j]可以由两个状态转移过来:1、f[i-1,j]       2、f[i-1,j-1]

    对于f[i-1,j],它想要转移成f[i,j],说明第i张牌没有被发动。所以f[i,j]=f[i,j]+f[i-1,j]*(1-p[i])r-j

    对于f[i-1,j-1],他想要转移成f[i,j],说明第i张牌被发动了。所以f[i,j]=f[i,j]+f[i-1,j-1]*(1-(1-p[i])r-j+1)

    代码:

    var
      pp,f:array[0..220,0..132]of double;
      d:array[1..220]of longint;
      g,p:array[1..220]of double;
      ans:double;
      i,j,t,n,r:longint;
    begin
      read(t);
      while t>0 do
      begin
        read(n,r);
        for i:=1 to n do
          read(p[i],d[i]);
        for i:=1 to n do
        begin
          pp[i,0]:=1;                                                //pp数组为预处理出的(1-p[i])任意次方数
          for j:=1 to r do
            pp[i,j]:=pp[i,j-1]*(1-p[i]);
        end;
        f[0,0]:=1;
        for i:=1 to n do
        begin
          f[i,0]:=f[i-1,0]*pp[i,r];
          for j:=1 to r do
            f[i,j]:=f[i-1,j]*pp[i,r-j]+f[i-1,j-1]*(1-pp[i,r-j+1]);
        end;
        fillchar(g,sizeof(g),0); 
        g[1]:=1-pp[1,r]; ans:=g[1]*d[1];
        for i:=2 to n do
        begin
          for j:=0 to r do
            g[i]:=g[i]+f[i-1,j]*(1-pp[i,r-j]);
          ans:=ans+g[i]*d[i];
        end;
        writeln(ans:0:10);
        dec(t);
      end;
    end.
  • 相关阅读:
    elasticsearch入门 (三 ik 分词器安装)
    elasticsearch入门(二 基础api实例)
    elasticsearch入门(一 基础搭建)
    mysql 错误代码 1045 解决
    信号强度概念
    c语言中,在结构体中如何将void *转存为具体需要的数据类型
    我的论文
    I2C 上拉电阻选择计算公式
    SD卡两种操作模式在项目中应用的比较
    2017 年 年会过后的感想
  • 原文地址:https://www.cnblogs.com/WR-Eternity/p/9773135.html
Copyright © 2020-2023  润新知