Poj 2300

来源:互联网 发布:mac ps做图 编辑:程序博客网 时间:2024/05/15 08:57

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);            }        }    }}

总结

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

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

原创粉丝点击