UVA 12585 Poker End Games 解题报告

比赛总结

题目

题意:

两个人玩扑克牌,A每局输赢的概率都是0.5.如果A有a张,B有b张,c=min(a,b),则该局获胜的人可从输的一方得到c张牌。谁先失去所有牌就输掉游戏。给出初始局面,求游戏进行的轮数的期望和A获胜的概率。

题解:

初看是概率DP,但是因为是个图所以不好写,然后又用高斯消元,但是某些局面某些矩阵元素会超过long long。测了几个自己的样例,发现获胜的概率就是a/(a+b),而进行的轮数直接搜索就可以:一个局面(a!=b)只有两个子局面,立刻结束或者继续,因为概率都是0.5,所以每搜一层就乘0.5,搜到25层以后已经对答案没什么影响了,可以直接忽略。

a、b的和为奇数时可以直接输出2。



//Time:
//Length:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define MAXN 310
#define MP(x,y) make_pair(x,y)
#define FI first
#define SE second
int a,b;
int gcd(int a,int b)
{
    while(a%b!=0)   a%=b,swap(a,b);
    return b;
}
double dfs(int a,int b,int dep)
{
    if(dep>25)  return 0;
    if(a==0||b==0)  return 0;
    int t=min(a,b);
    return (dfs(a-t,b+t,dep+1)+dfs(a+t,b-t,dep+1))*0.5+1;
}
int main()
{
    //freopen("/home/moor/Code/input","r",stdin);
    int ncase,t;
    scanf("%d",&ncase);
    for(int hh=1;hh<=ncase;++hh)
    {
        scanf("%d%d",&a,&b);
        t=gcd(a,b);
        a/=t,b/=t;
        printf("Case %d: ",hh);
        printf("%.6f %.6f\n",(a+b)&1?2:dfs(a,b,1),a*1.0/(a+b));
    }
    return 0;
}


你可能感兴趣的:(UVA 12585 Poker End Games 解题报告)