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 }