http://codeforces.com/contest/148/problem/D
题目大意:
给出w只白老鼠,b只黑老鼠,公主和龙轮流取老鼠,公主先手,龙取老鼠时会吓跑一只老鼠,先取出白老鼠的人赢,如果没人取到白老鼠,那么龙赢。问公主赢的概率。
思路:f[i][j]代表目前有i条白老鼠,j条黑老鼠的概率,我们一边dp一边统计答案,当龙把所有黑老鼠弄走而且还有白老鼠存在,我们就把win加上f[i][j],或者公主拿到白老鼠,就把win加上f[i][j],而我们的dp值只dp游戏没有结束的部分,
坑点:我在循环后面判断了一下当前的f[i][j]是否大于eps,这TM居然造成了精度误差,
我要没去试着改掉这里估计得改个一下午
1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstring> 5 #include<iostream> 6 const double eps=1e-9; 7 int n,m; 8 double f[1005][1005]; 9 int id[2005]; 10 int read(){ 11 int t=0,f=1;char ch=getchar(); 12 while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} 13 while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} 14 return t*f; 15 } 16 int main(){ 17 n=read();//白老鼠 18 m=read();//黑老鼠 19 if (n==0){ 20 printf("0.000000000"); 21 return 0; 22 } 23 f[n][m]=1.0; 24 id[n+m]=1; 25 double win=0,lose=0; 26 for (int i=n+m-1;i>=0;i--) 27 if ((n+m-i)%3==0) id[i]=1; 28 else if ((n+m-i)%3==1) id[i]=2; 29 for (int i=n;i>=0;i--) 30 for (int j=m;j>=0;j--){ 31 if (i==0) continue; 32 if (j==0){ 33 if (id[i+j]==1) win+=f[i][j]; 34 else if (id[i+j]==2) lose+=f[i][j]; 35 continue; 36 } 37 if (id[i+j]==1){ 38 double t1=((double)i)/((double)i+j); 39 win+=t1*f[i][j]; 40 double t2=1.0-t1; 41 if (j>0) f[i][j-1]+=t2*f[i][j]; 42 } 43 if (id[i+j]==2){ 44 double t1=((double)i)/((double)i+j); 45 double t2=1.0-t1; 46 lose+=t1*f[i][j]; 47 double t21=t2*((double)i)/((double)i+j-1); 48 double t22=t2-t21; 49 if (i==1) 50 lose+=t21*f[i][j]; 51 else 52 f[i-1][j-1]+=f[i][j]*t21; 53 54 if (j>=2){ 55 if (j==2) win+=f[i][j]*t22; 56 else 57 f[i][j-2]+=f[i][j]*t22; 58 } 59 } 60 } 61 printf("%.9f ",win); 62 return 0; 63 }