一,题目
二,翻译
龙和公主正在争论除夕夜该做什么。龙建议飞到山上看仙女在月光下跳舞,而公主则认为她们应该早点睡觉。他们迫切希望达成一项友好的协议,所以他们决定把这件事留给机会。
他们轮流从最初装有w只白老鼠和b只黑老鼠的袋子里抽出一只老鼠。第一个画白老鼠的人获胜。在每只老鼠被龙抽走后,袋子里的其他老鼠都会惊慌,其中一只从袋子里跳出来(公主小心翼翼地抽走她的老鼠,没有吓到其他老鼠)。公主先抽签。公主获胜的概率是多少?
如果袋子里没有更多的老鼠,而且没有人画出一只白老鼠,那么龙就赢了。从袋子里跳出来的老鼠不被视为抽签(不确定获胜者)。一旦一只老鼠离开了袋子,它就再也不会回到袋子里。每只老鼠从袋子里抽出来的概率都与其他老鼠一样,每只老鼠跳出袋子的概率也与其他老鼠相同。
输入
唯一一行输入数据包含两个整数w和b(0 ≤ w b ≤ 1000).
输出
输出公主获胜的概率。如果其绝对或相对误差不超过10,则认为答案正确 - 9
样本1
输入副本输出副本
1 3
0.500000000
样本2
输入副本输出副本
5 5
0.658730159
笔记
让我们来看看第一个样本。公主在第一次转弯时抽到一只白老鼠,并立即获胜的概率为1/4。龙在第一回合抽到一只黑老鼠而没有获胜的概率是3/4*2/3=1/2。之后,袋子里剩下两只老鼠——一只黑色,一只白色;其中一个跳了出来,另一个在第二个转弯时被公主拉住了。如果公主的老鼠是白色的,她就会获胜(概率是1/2*1/2=1/4),否则没有人会得到白老鼠,所以根据规则,龙会获胜。
三,思路
用个dp数组记录搜索情况,横向记录公主某次操作后还剩的黑老鼠,纵向记录还剩的白老鼠,反过来也行,然后用dfs搜就行。
四,代码
#include<bits/stdc++.h>
using namespace std;
double dp[1005][1005]={0};
int w=0,b=0;
double dfs(int x,int y)
{
if(x==0) return 0;
if(y==0) return 1;
if(dp[x][y]>0) return dp[x][y];
double ans=1.0*x/(x+y);
if(y>=3) ans+=1.0*y/(x+y)*(y-1)/(x-1+y)*(1.0*x/(x+y-2)*dfs(x-1,y-2)+1.0*(y-2)/(x+y-2)*dfs(x,y-3));
if(y==2) ans+=1.0*y/(x+y)*(y-1)/(x-1+y)*dfs(x-1,y-2);
return dp[x][y]=ans;
}
int main()
{
cin>>w>>b;
printf("%.9lf",dfs(w,b));
return 0;
}