HDU-1204 糖果大战(概率DP)

本文探讨了两个人通过玩24点游戏争夺糖果的情景,利用博弈论的方法计算了第一个人赢得比赛的概率。通过建立递推关系和求解特征方程,最终得出获胜概率的精确表达式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意

两个人分别有 N,MN,M 颗糖果,现在他们在玩 2424 点,已知这两人分别想出来的概率为 p,qp,q,赢可以获得对方的一颗糖,当某个人糖被拿完就判输,求第一个人胜利的概率。
1N,M501≤N,M≤50

思路

赢的概率为 p(1q)p(1−q),输的概率为 q(1p)q(1−p) ,那么这两个数分别除以 p(1q)+q(1p)p(1−q)+q(1−p) 就能排除和的情况。
问题就转化成了已知第一个人赢的概率为 pp​ ,第二个人赢的概率为 qq​ (p+q=1)(p+q=1)​ ,求第一个人获胜概率。
anan 为第一个人手中有 nn 个糖果的获胜概率。
an=pan+1+qan1, a0=0a0=0, aN+M=1aN+M=1, 求 aNaN.
an1=qan+pan2an−1=qan+pan−2
an=1pan1qpan2an=1pan−1−qpan−2
写出特征方程 x21px+qp=0x2−1px+qp=0
x21px+1pp=0x2−1px+1−pp=0
解得x1=1pp=qpx1=1−pp=qp, x2=1x2=1.
设通项为 an=K1(qp)n+K21nan=K1(qp)n+K21nan=K1(qp)n+K2an=K1(qp)n+K2
a0=K1+K2,aN+M=K1(qp)N+M+K2a0=K1+K2,aN+M=K1(qp)N+M+K2
K1+K2=0,K1(qp)N+M+K2=1K1+K2=0,K1(qp)N+M+K2=1
解得 K1=1(qp)N+M1,K2=1(qp)N+M1K1=1(qp)N+M−1,K2=−1(qp)N+M−1
通项为 an=(qp)n1(qp)N+M1an=(qp)n−1(qp)N+M−1
aN=(qp)N1(qp)N+M1aN=(qp)N−1(qp)N+M−1
直接套公式解决。

代码

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define FOR(i,x,y) for(int i=(x);i<=(y);i++)
#define DOR(i,x,y) for(int i=(x);i>=(y);i--)
typedef long long LL;
using namespace std;

int main()
{
    int n,m;
    double p,q;
    while(~scanf("%d%d%lf%lf",&n,&m,&p,&q))
    {
        double P=p*(1.0-q),Q=q*(1.0-p);
        if(m==0)printf("1.00\n");
        else if(n==0)printf("0.00\n");
        else if(P==Q)printf("%.2lf\n",1.0*n/(n+m));
        else if(P==1)printf("1.00\n");
        else if(Q==1)printf("0.00\n");
        else printf("%.2lf\n",(1.0-pow(Q/P,n))/(1.0-pow(Q/P,n+m)));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值