Poj 2300

0 篇文章 0 订阅

Poj 2300

http://poj.org/problem?id=2300

题目大意

赌博游戏
Stan和Ollie每年夏天都会来到Ex,Stan喜欢玩Crown & Anchor.
Crown & Anchor是一个猜图案的游戏:Crown, Anchor, Club, Diamond, Heart, Spade一共六种图案
轮子旋转并最终停止在一个拥有3个以上组合图案的位置。
如果斯坦赌注中有最终位置中指出的三个符号之一,他会收到他的本金和n倍押注的奖金,其中n是他的下注符号出现的次数。
以前每年,斯坦都在输钱,奥利嘲笑他。
今年,斯坦与奥利(Ollie)进行了一个下注:他要打败Ollie赚钱。
Ollie不蠢,意识到斯坦有可能会幸运地赢前几轮,所以他坚持认为,斯坦至少领先k轮才算斯坦赢。
Ex最多m轮的游戏 之后将会关闭,为了赢得Stan,Ollie必须在最多m轮内获得利润。
Stan藏了一手,他最近学会了蒙特卡洛的投注策略。这个想法是他先下最低的赌注。
如果他赢了,他会收取他的奖金,并再次给予最低的赌注。
如果他输了,他会下双倍的赌注,如果他赢下一轮,他将赢得足够的收益,以弥补以前的损失并赚取利润。
这一直下去,直到他赢了。 无论何时他赢了,他都会赢利,并以最低的赌注重新开始。
Stan认为这是一个伟大的战略,但是首先建立思想,并实施了一个限制 - 斯坦斯可以在任何轮下的最大赌注是多少。
(假定Stan无限多钱)
Stan修改了他的策略,以便如果他的投注数超过最大限额,他将以最低的下注开始,希望能够收回他的损失。
如果按照这个策略,Stan需要在K轮内保持领先,或者在第m+1轮之前,他就能获得胜利。 斯坦将赢得下注的几率是多少?

输入:
第一行输入包含n个测试用例数。
0≤k≤m≤30 ; 2≤l≤1000。
最小赌注为1。

输出:
一个0到1的概率

想法

不难猜想 每个图案的个数是一样的(不然就不会随机对一个图案下注了),这样就得出选定一个图案后:
转到有1个该图案的转板概率为2/14
转到有2个该图案的转板概率为1/14
转到有3个该图案的转板概率为1/14
转化为编程的思想
2/14:一倍收益 1/14:两倍收益 2/14:三倍收益 10/14:亏掉本钱

根据逻辑 代码如下:

//poj2300
//San
#include<iostream>
#include <iomanip>
using namespace std;
void count(int benifit, int bet, int round, double rate);
int k, m, l;
double frate;
double fail = 10.0 / 14;
double win1 = 2.0 / 14;
double win2 = 1.0 / 14;
double win3 = 1.0 / 14;
int winround = 0; //赢得轮数,当连续k轮收益大于0时直接胜利
int main()
{
    int n;
    frate = 0.0; //用于计算每次胜利的概率和
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        frate = 0;
        winround = 0;
        cin >> k >> m >> l;
        count(0, 1, 0, 1); //初始是 收益0、赌注1、轮数0、初始概率1
        cout << fixed << setprecision(4) << frate;//输出控制4位
    }
    return 0;
}
void count(int benifit, int bet, int round, double rate)
{
    if (benifit > 0)
        winround++;
    else
        winround = 0;
    if ((round >= m || winround >= k))
    {
        if (benifit>0)
            frate += rate;
    }
    else if (benifit>0)
    {
        count(benifit + bet, 1, round + 1, rate*win1);
        count(benifit + 2 * bet, 1, round + 1, rate*win2);
        count(benifit + 3 * bet, 1, round + 1, rate*win3);

        if (bet * 2>l)
        {
            if (benifit - bet > 0)
            {
                count(benifit - bet, 1, round + 1, rate*fail);

            }
            else
            {
                count(benifit - bet, 1, round + 1, rate*fail);

            }
        }
        else
        {
            if (benifit - bet > 0)
            {
                count(benifit - bet, 2 * bet, round + 1, rate*fail);

            }
            else
            {
                count(benifit - bet, 2 * bet, round + 1, rate*fail);

            }
        }
    }
    else
    {
        count(benifit + bet, 1, round + 1, rate*win1);
        count(benifit + 2 * bet, 1, round + 1, rate*win2);
        count(benifit + 3 * bet, 1, round + 1, rate*win3);
        if (bet * 2>l)
        {
            if (benifit - bet > 0)
            {
                count(benifit - bet, 1, round + 1, rate*fail);
            }
            else
            {
                count(benifit - bet, 1, round + 1, rate*fail);
            }
        }
        else
        {
            if (benifit - bet > 0)
            {
                count(benifit - bet, 2 * bet, round + 1, rate*fail);
            }
            else
            {
                count(benifit - bet, 2 * bet, round + 1, rate*fail);
            }
        }
    }

}

总结

概率事件多次重复,是递归的象征,我在多次提交的过程中出现了超时的现象,应该可以在逻辑上进一步优化。

应该有统计的方法的。。后来想不出了 先放着吧。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值