http://codeforces.com/problemset/problem/148/D
有n个白球m个黑球,公主和龙玩游戏,公主每次随机取一个球,龙每次随机取一个球,在龙取完之后袋子里的球会随机消失一个(消失的球不被算作任何一个人所取走的且后面不会再出现),谁先取到白球就算胜利,如果最后没有球了但是还没决出胜负那么龙就是获胜者,公主先手,问公主获胜的概率。
f[i][j]表示轮到公主取的时候局面是i个白球j个黑球的概率,那么答案就是SUM{ f[i][j]*i/(i+j) }。
边界是f[n][m]=1,由于要让游戏进行下去所以递推的时候双方都要取黑球(如果有一方取走白球那游戏结束没有下一个回合了,我们只需考虑公主面临的所有状态就好了),公主先取走一个黑球,龙取走一个黑球,消失一个白球/黑球之后对应的两个状态又是公主回合的状态了。
1 #include<iostream> 2 #include<cstring> 3 #include<queue> 4 #include<cstdio> 5 #include<stack> 6 #include<set> 7 #include<map> 8 #include<cmath> 9 #include<ctime> 10 #include<time.h> 11 #include<algorithm> 12 using namespace std; 13 #define mp make_pair 14 #define pb push_back 15 #define debug puts("debug") 16 #define LL long long 17 #define pii pair<int,int> 18 #define eps 1e-9 19 #define inf 0x3f3f3f3f 20 21 double f[1010][1010]; 22 int main() 23 { 24 int t,i,j,k,n,m,u,v; 25 scanf("%d%d",&n,&m); 26 f[n][m]=1.0; 27 for(i=n;i>=1;--i){ 28 for(j=m;j>=1;--j){ 29 if(f[i][j]){ 30 double black=f[i][j]*((double)j/(i+j))*(double(j-1)/(i+j-1)); 31 if(i+j-2>0&&j-2>=0&&i-1>=0) 32 f[i-1][j-2]+=black*(i)/(i+j-2); 33 if(j-3>=0&&i+j-2>0) 34 f[i][j-3]+=black*(j-2)/(i+j-2); 35 } 36 } 37 } 38 double ans=0; 39 for(i=0;i<=n;++i){ 40 for(j=0;j<=m;++j){ 41 if(i+j) 42 ans+=f[i][j]*i/(i+j); 43 } 44 } 45 46 printf("%.9f ",ans); 47 return 0; 48 }