hdu4870 一个人有两个账号,每次拿rating低的号打,p的概率加50,1-p的概率减100,求任意一个号到1000分的期望场数:期望dp+高斯消元

每50分为1分,减少状态。

首先dp[i][j]=p*(dp[i+1][j]或dp[j][i+1])+(1-p)*dp[i-2][j]+1 这是入门的期望公式了

利用id(i,j)=(i-i*i)/2+20*i+j来标序

形成环了,高斯消元解出方程,x[0]即为dp[0][0]的期望了==

 1 #include<stdio.h>
 2 #include<math.h>
 3 #include<string.h>
 4 #include<algorithm>
 5 using namespace std;
 6 #define eps 1e-8
 7 int cal(int i,int j)
 8 {
 9   return (i-i*i)/2+20*i+j;
10 }
11 double g[235][235],x[235];
12 int row,col;
13 int guass()
14 {
15   int tr,tc,i,j,max_r;
16   for (tr=0,tc=0;tc<=col;tc++)
17   {
18     max_r=tr;
19     for (i=tr;i<=row;i++)
20       if (fabs(g[i][tc])>fabs(g[max_r][tc])) max_r=i;
21     if (fabs(g[max_r][tc])<eps) return 0;
22     if (max_r!=tr){
23       for (j=tc;j<=col;j++) swap(g[max_r][j],g[tr][j]);
24       swap(x[max_r],x[tr]);
25     }
26     for (j=tc+1;j<=col;j++) g[tr][j]/=g[tr][tc];
27     x[tr]/=g[tr][tc]; g[tr][tc]=1;
28     for (i=0;i<=row;i++)
29       if (i!=tr)
30       {
31         for (j=tc+1;j<=col;j++) g[i][j]-=g[i][tc]*g[tr][j];
32         x[i]-=x[tr]*g[i][tc]; g[i][tc]=0;
33       }
34     tr++;
35   }
36   return 1;
37 }
38 int main()
39 {
40   int i,j,id,tmp_id,ti,tj;
41   double p;
42   while (~scanf("%lf",&p))
43   {
44     memset(g,0,sizeof(g));
45     memset(x,0,sizeof(x));
46     for (i=0;i<=20;i++)
47       for (j=i;j<=20;j++)
48       {
49         id=cal(i,j);
50         g[id][id]+=1;
51         if (i==20||j==20) continue;
52         ti=min(i+1,j); tj=max(i+1,j);
53         tmp_id=cal(ti,tj);
54         g[id][tmp_id]-=p;
55         ti=max(0,i-2); tj=j;
56         tmp_id=cal(ti,tj);
57         g[id][tmp_id]-=1-p;
58         x[id]+=1;
59       }
60     row=col=230;
61     guass();
62     printf("%.6lf\n",x[0]);
63   }
64   return 0;
65 }
View Code

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4870

posted on 2015-03-05 21:35  xiao_xin  阅读(132)  评论(0编辑  收藏  举报

导航