概率 方程组 递推

Alice和Bob赌糖果

http://www.nowcoder.com/questionTerminal/14f52a1dc30e4da7b0c1af14240ea349

首先,需要计算单局Alice获胜的概率p.

方法1

这个由于l,r,L,R都是非常小的范围,所以,直接枚举每一个点,统计获胜点和失败点的个数即可求得。

方法2

如果l,r,L,R并不是100以内,那么需要通过皮克定理,线性规划,计算获胜区域内的整点数目和失败区域的整点数目。l和L的大小关系3种,同理r和R也是三种,共9种情况。当然,可以通过交换x和y以及仔细观察发现可以合并的情况。

其次,计算题目要求的概率

此时,问题可以表述成,已知A为n,B为m,每次,A有p的概率从B赢1点,否则,(1-p)的概率输一点。当一方为0游戏结束,问最终结束的状态是A有n+m的概率是多少。
我们有(u,v)表示A有u个,B有v个的状态。显然游戏结束状态只有两种,我们要求的是最终状态为的概率。
显然不论什么状态都有.因此,我们只需确定第一维的即确定了一个状态。
表示当前状态是,最终状态变成的概率。
显然有.
对于,有方程.
因此,一共有个方程,未知数一共有个,然后都是一次方程。可解。
当然,没有必要上高斯消元解线性方程组,我们稍微手动解一下方程。
我们不妨将都用表示出来,可以发现都可以表示成的形式。
不难发现,
之后,再将代入方程,解出,与进行对比,不难发现的递推式: .
.

code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

inline ll read()
{
    ll x = 0;
    bool f = 0;
    char ch = getchar();
    while (ch < '0' || '9' < ch)
        f |= ch == '-', ch = getchar();
    while ('0' <= ch && ch <= '9')
        x = x * 10 + ch - '0', ch = getchar();
    return f ? -x : x;
}

void write(ll a)
{
    if (a < 0)
    {
        putchar('-');
        a = -a;
    }
    if (a >= 10)
    {
        write(a / 10);
    }
    putchar(a % 10 + '0');
}

void writeln(ll a,ll c='\n') {
    write(a);putchar(c);
}

double cal_p(ll l, ll r, ll L, ll R) {
    int a = 0,b = 0;
    for (ll i = l; i <= r; ++i)
        for (ll j = L; j <= R; ++j) {
            if (i>j) ++a;
            if (i<j) ++b;
        }
    return (1.0*a)/double(a+b);
}

double cal(ll a, ll n, double p) {
    vector<double>k(n);
    k[1] = p;
    for (int i = 2; i < n; ++i)
        k[i] = p/(1-(1-p)*k[i-1]);
#ifdef debugmode
    for (int i = 1; i < n; ++i)
        printf("%.05lf   ",k[i]);
    putchar('\n');
#else
#endif
    auto ans = double(1);
    for (int i = a; i < n; ++i)
        ans *= k[i];
    return ans;
}

int main()
{

    ll n,l,r,m,L,R;
    n = read(); l = read(); r = read();
    m = read(); L = read(); R = read();
    if (n == 0) {
        puts("0.00000");
        return 0;
    } else if (m == 0) {
        puts("1.00000");
        return 0;
    }
    auto p = cal_p(l,r,L,R);
#ifdef debugmode
    cout<<p<<endl;
#else
#endif
    auto q = 1-p;
    auto a = p*n;
    auto b = q*m;
    auto ans = cal(n,n+m,p);
    printf("%.5lf\n",ans);
    return 0;
}
全部评论

相关推荐

10-16 23:21
已编辑
门头沟学院 Java
点赞 评论 收藏
分享
11-06 12:53
吉林大学 Java
如题,ip属地末九,计算机科班大三本科生。想找一段寒假实习,也是第一次找实习。&nbsp;从大二暑假7月开始准备Java后端,前期有点磨叽,导致现在手忙脚乱。目前第二个项目黑马点评快写完了,第一个项目是苍穹外卖(两个项目都是烂大街的,这就很头大)。算法题在lc上从大二至今陆续刷了将近六百题,hot100已过一遍,面试150目前刷了一半。八股刚看了不到一周,想请教一下各位牛友,这一版简历哪些地方需要继续改进,接着优化?&nbsp;同时,是现在立即开始投递,边投边背八股,完善项目。还是说八股再背个小半个月再开始投递比较好一点,我现在担心的是到了这个月下旬或者12月再开始投递简历面试会有点晚,听同学说到年底hc数量会大...
mikeu04:简历顶部留名字即可,你写“后端开发实习生-Java”就是把自己的方向限制死了。我建议把这揉在个人简介里,说你对后端开发充满热情就行。性别出生年份以及微信号不是必须的。 把个人简介从教育背景里拿出来,第一个写。你的个人简介有点太泛了。把“爱好中长跑”去了,加点数字(“拥有xxx年的xxx经历”),加点你最熟的几个语言或技术栈。和别人的简介区分开来。 专业技能放项目经历前面。面试官一般会优先看这个再往下看你做了什么项目来考察你是否具备这些技能。实习我不是很清楚,但像Redis, JVM, 消息模型,计算机网络这些属于基本知识。你如果了解GCP, AWS, Docker 这些实际生产工具就可以把八股知识换掉。 项目简介可以和工作内容揉在一起。项目简介还是太长了,就一句话,“开发了一个基于【1,2个主要框架】为【目标客户群体】的【产品类型】, 实现了【产品价值】”。产品价值不是功能。比如一个在线计算器,它的功能是算数,但它的价值可以是让人在没带计算器的情况下算数(可访问性)或比手算效率提升了80%。工作内容多加点数字,你这个产品有多少人用了?浏览量是多少?技术上xxx性能提升了多少%?(实在想不出来就丢给deepseek :) 11 月理论上秋招已经结束了。八股是背不完的。无脑投,刷笔试,中了面试邀请就突击面经八股,没问题的。
大厂面试问八股多还是项目...
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务