博弈论4

Stone Game

 

Time Limit:   1000MS       Memory Limit:   65535KB
Submissions:   1       Accepted:   1

 

Description
AC and WA love to collect stones and play games with them. Up till now they have collected Na white stones and Nb black stones, and they are going to play a new game. The rules of the game is as follows: (1) All the stones are put into a pocket initially, so that each stone has equal possibility to be picked up, and each time a stone is picked up randomly. (2) The two players take turns to pick up a stone, if the stone is black, the current player should put it back to the packet; otherwise the player could keep the stone. (3) Whoever picks up the last white stone wins the game. Now they haven't decided who palys first. To make a better decision, AC have asked you, an excellent programmer, to calculate the winning possibility for the first player. Since they are going to start playing soon, you must finisth the job as quickly as possible.

 

Input
The first line is a single number n, the number of the test cases followed. In the next n lines, each line contains two non-negative intergers, Na and Nb(0 =< Na, Nb <= 64).

 

Output
For each test case, output a real number indicating the possibility for the first player to win. The answer should be rounded to 6 digits after the decimal point. No extra spaces are allowed.

 

Sample Input

3
1 0
0 1
3 10

 

Sample Output

1.000000
0.000000 0.500282

分析:

大致题意:有na个白石头和nb个黑石头,两个人轮流取石头,如果取到黑石头就放回,取到白石头就拿出,谁取到最后一颗白石头,谁就赢;问第一个取石头的人胜的几率

解题思路:用到递推,用win数组存胜的概率,win[i]表示还剩i个白石头时,取的那个人获胜的概率

①在当前情况下,取到白石头的概率(i/(i+nb)),取到黑石头的概率(nb/(i+nb)),很明显当没白石头时,第一个人取到的概率为0,即win[0]=0              

②当i>1时,摸到白石头,还没赢,则需乘(1-win[i-1]),表示对方面对i-1个白石头不赢;摸到黑石头,同样也要乘(1-win[i]),表示对方面对i个白石头不赢

这里即可推出:win[i]=(i/(i+nb))*(1-win[i-1])+(nb/(i+nb))*(1-win[i]),即有win[i]=(i*(1-win[i-1]+nb)/(i+2nb)),且win[0]=0

代码如下:

 

 1 # include<stdio.h>
 2 int main()
 3 {
 4     int nCase;
 5     int na,nb,i;
 6     double win[80];
 7     scanf("%d",&nCase);
 8     while(nCase--)
 9     {
10         win[0]=0;
11         scanf("%d %d",&na,&nb);
12         for(i=1;i<=na;i++)
13             win[i]=(i*(1-win[i-1])+nb*1.0)/(i+2*nb);
14         printf("%0.6f\n",win[na]);
15     }
16     return 0;
17 }

 

posted on 2014-09-16 01:00  会敲键盘的猩猩  阅读(118)  评论(0编辑  收藏  举报