题解:dp[x][y]表示当前剩余x只白鼠和y只黑鼠的情况下赢的概率,所以当前赢的概率为x/(x+y),然后考虑上两人选黑鼠情况下跑掉白鼠或者黑鼠这两种情况后赢的概率;
下面这dp推论公式是这样理解的,我举个例子
状态流程:dp状态1--取完两只跑掉一只-->dp状态2--取完两只跑掉一只-->dp状态3..... 比如dp[4][4]--取完两只跑掉一只-->dp[3][2]或dp[4][1],OK?
理解方式:就像深度优先搜索里面的回溯一样。。对,就是酱紫的~
dp[状态1]=(1到2的概率)*dp[状态2]
dp[状态2]=(2到3的概率)*dp[状态3]
dp[状态3]=(3到4的概率)*dp[状态4]
dp[状态4]=(4到5的概率)*dp[状态5].........
归纳起来就是dp[状态1]=(1到2)*(2到3)*(3到4)*(4到5)*...*dp[最终不能再取的状态],不能再取状态就是没有黑鼠了的状态,所以初始化的时候应该把黑鼠为0白鼠从0到b都设置为概率1,因为没有黑鼠只有白鼠,随便取都是赢
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <vector> #include <cmath> #include <algorithm> #define Max(a,b) (a>b?a:b) #define Min(a,b) (a<b?a:b) #define mod 1000000007 #define LL __int64 #define M 1010 using namespace std; double dp[M][M]; int main() { int n,m,i,j,k,l; while(cin>>n>>m) { memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++)dp[i][0]=1;//没有 for(i=1;i<=n;i++)// for(j=1;j<=m;j++)// { dp[i][j]=1.0*i/(i+j);//当前赢的概率 if(j>=2)dp[i][j]+=dp[i-1][j-2]*1.0*j/(i+j)*1.0*(j-1)/(i+j-1)*1.0*i/(i+j-2);//dp[下一个状态1]*这个状态转移到下个状态的概率--两人取黑跑白 if(j>=3)dp[i][j]+=dp[i][j-3]*1.0*j/(i+j)*1.0*(j-1)/(i+j-1)*1.0*(j-2)/(i+j-2);//dp[下一个状态2]*这个状态转移到下个状态的概率--两人取黑跑黑 } printf("%.9lf\n",dp[n][m]); } return 0; }
dp[状态1]=(1到2的概率)*dp[状态2]