51nod 1630 B君的竞技场

1630 B君的竞技场

原题连接:
https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1630

概率题。纯数学。

题目中的四个要求:

我们将竞技场规则简化如下:
1. 每个人进入竞技场后,会等概率随机匹配一个人,匹配到的人与当前胜利和失败场数无关。
2. 胜利达到x场,或失败达到y场后,退出竞技场,根据退出时的胜利场数获得奖励,不能中途放弃。
3. 水平高的选手,总能战胜水平低的选手,不存在水平相等的人。
4. 竞技场有无穷多的人。
因为题目给定无穷的人数,其实暗示人数不重要。可以某种方法消去 n 的影响

我们设总人数为:n

因为没有实力相同的两个人。所以每个人相对实力是确定的。(也就是说实力排名是确定的)
给出 n 个实力级别:

1,2,3,4,5,6,....n

那么 b 君的实力级别为 i 时她的胜场概率为:

P(i)=i1n

设 B君的胜场概率实为 P(i) 时,得分期望为 E(P(i))
则B君的实际望为:

answer=1ni=1nE(P(i))=i=1n1nE(P(i))=i=1n1nE(i1n)=i=0n11nE(in)

所以, answer 等于 n 趋近于时候的答案:

answer=limn>i=0n11nE(in)

在任何一本高数书上都可以找到计算上面和式的方法。
对于一般的积分计算,等效于把区间无限微分后得到的答案。
例如:

baf(x) dx

如果对于 x[a,b] ,函数 f(x) 都是有意义的
我们把区间 [a,b] 分割为 n

n足够大时。对于每一小段。我们认为 f(x) 变化很小。

此时第 i 小段。与x轴和曲线 f(x) 围成的面积近似为( n> 时可以认为相等):

banf((i1)(ba)n)

所以:

baf(x) dx=limn>i=1nbanf((i1)(ba)n)=limn>i=0n1banf(i(ba)n)

所以:

answer=10E(p) dp=limn>i=0n11nE(in)

p 是b君每一场比赛胜利的概率。

当b君每场比赛胜利概率为 p 时。他得分的期望分为两部分。

第一部分:最后一场比赛胜利。总胜利场次x。退出游戏
第二部分:最后一场比赛失败。总是败场次y。退出游戏

<script type="math/tex; mode=display" id="MathJax-Element-607"></script>

注意。退出游戏的原因要么因为失败太多。要么因为胜利太多。

<script type="math/tex; mode=display" id="MathJax-Element-608"></script>

对于第一部分。必然胜利了x场。枚举失败场次,记 失败了 k 场:

则。这部分的贡献为:

0<=k<ypx(1p)k(x+k1k)

上面的公式可以理解为:当我们比赛 x+k 场时。最后一场比赛必须胜利。那么失败场次可供选择的位置只有 x+k1
同理。记 t 胜利场次。第二部分的贡献为

0<=t<xpt(1p)y(y+t1t)

所以 E(p) 有:
E(p)=0<=k<ypx(1p)k(x+k1k)+0<=t<xpt(1p)y(y+t1t)
所以:
answer=10E(p) dpE(p)=0<=k<ypx(1p)k(x+k1k)+0<=t<xpt(1p)y(y+t1t)
可以用 辛普森积分 的模版计算上面在区间 [0,1] 上的积分
对于组合数可以利用帕斯卡公式求的:
(nk)=(n1k)+(n1k1)
下面是AC代码
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
typedef long long LL;
const LL N=10000;
LL C[50][50]={1};
LL W[50][50];
LL x,y;
void init()
{
    for(int n=1;n<41;n++)
    {
        C[n][0]=1;
        for(int k=1;k<=n;k++)
        {
            C[n][k]=C[n-1][k-1]+C[n-1][k];
        }
    }
}
double pow(double P,LL b)
{
    double ans=1;
    while(b)
    {
        if(b&1)
            ans*=P;
        b>>=1;
        P*=P;
    }
    return ans;
}
double f( double P)
{
    double ans=0;
    for(LL j=0;j<y;j++)
    {
        ans+=(double)(x*W[x][j])*pow(P,x)*pow(1-P,j);
    }
    for(LL j=0;j<x;j++)
    {
        ans+=(double)(j*W[j][y])*pow(P,j)*pow(1-P,y);
    }
    return ans;
}
double simpson(double a,double b,LL n)
{
    const double h=(b-a)/n;
    double ans=f(a)+f(b);
    for(int i=1;i<n;i+=2)ans+=4*f(a+i*h);
    for(int i=2;i<n;i+=2)ans+=2*f(a+i*h);
    return ans*h/3;
}
int main ()
{
    init();
    scanf("%lld %lld",&x,&y);
    for(LL j=0;j<y;j++)
        W[x][j]=C[x+j-1][j];
    for(LL j=0;j<x;j++)
        W[j][y]=C[y+j-1][j];
    printf("%lf\n",simpson(0,1,N));
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值