题意描述:公主和龙依次从一个装有w个白老鼠,b个黑老鼠的袋子里抓老鼠,公主先抓,龙抓完后会有一只老鼠跑出来,所有老鼠被选中或跑出来都不再出现在袋子中,若都没有抓到白老鼠而袋子空判龙赢,问公主赢的概率。
首先想到问题很复杂,在于龙抓完老鼠还会跑一只,所以不能直接算,用DP;
win[ i ] [ j ] 表示当有i只白老鼠和j只黑老鼠公主赢的概率,lost[ i ] [ j ] 表示有i白老鼠,j黑老鼠龙输的概率,那么可以产生转移方程
win[ i ] [ j ] = i/(i+j) //即公主抓到了白老鼠
win[ i ] [ j ]+=j/(i+j)*lost[ i ] [ j-1 ] //公主抓到了黑老鼠但是龙在下一个状态失败了
lost[ i ] [ j ] = j/(i+j)* (j-1)/(i+j-1)*win[ i ][ j-2] //龙抓到一只黑老鼠,跑掉的也是黑老鼠,且在下一个状态公主赢了
lost[ i ] [ j ]+=j/(i+j)*i/(i+j-1)*win[ i-1 ] [ j-1 ] //龙抓到黑老鼠,跑掉一只白老鼠且下一状态公主赢
#include<cstdio>
#include<iostream>
using namespace std;
#define N 1005
double win[N][N];
double lost[N][N];
void init(){
int i,j;
for(i=1;i<N;i++) win[i][0]=1;
for(i=1;i<N;i++){
for(j=1;j<N;j++){
win[i][j]=i*1.0/(i+j);
win[i][j]+=j*1.0/(i+j)*lost[i][j-1];
lost[i][j]=i*1.0/(i+j)*win[i-1][j-1]*j*1.0/(i+j-1);
lost[i][j]+=j*1.0/(i+j)*win[i][j-2]*(j-1)*1.0/(i+j-1);
}
}
}
int main(){
int a,b;
init();
while(scanf("%d %d",&a,&b)!=EOF){
printf("%.9f\n",win[a][b]);
}
return 0;
}