hdu 4074 Darts

思路:p[n][m][0]表示A为n,B为m,A为先手胜的概率;

         p[n][m][1]表示A为n,B为m,B为先手胜的概率。

         d[i]表示圆盘上数字的大小。

容易得到表达式为:

      

代码如下:

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<vector>
 7 #define M 502
 8 using namespace std;
 9 double p[M][M][2];
10 int d[]={5,20,1,18,4,13,6,10,15,2,17,3,19,7,16,8,11,14,9,12,5,20};
11 int cal(int a,int b){ return a>=b?a-b:a;}
12 int main()
13 {
14     int n,m;
15     for(n=0;n<M;n++){
16         p[0][n][0]=1;
17         p[n][0][1]=1;
18     }
19     for(n=1;n<M;n++)
20     for(m=1;m<M;m++){
21         if(n<=20) p[n][m][0]=n/20.0;
22         if(m<=20) p[n][m][1]=m/3.0;
23         for(int k=0;k<90;k++){
24             double a=0;
25             for(int i=1;i<=20;i++)
26                 a+=p[cal(n,d[i])][m][1];
27             p[n][m][0]=1-a/20.0;
28             double b=1e300;
29             for(int i=1;i<=20;i++){
30                 double c=0;
31                 for(int j=-1;j<=1;j++)
32                     c+=p[n][cal(m,d[i+j])][0];
33                 c/=3.0;
34                 if(b>c) b=c;
35             }
36             p[n][m][1]=1-b;
37             if(n>20) break;
38         }
39     }
40     while(scanf("%d",&n)&&n){
41         printf("%.12lf %.12lf\n",p[n][n][0],p[n][n][1]);
42     }
43     return 0;
44 }
View Code

 

 

 

 

posted @ 2013-10-10 20:11  _随心所欲_  阅读(218)  评论(0编辑  收藏  举报