题意:模拟大富翁,求在t步之内走到终点的概率。

题解:记忆化搜索,dp[p][k]为在p点走了k步且最后到达终点的概率,其它都是简单模拟。

View Code
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const double eps=1e-8;
 6 const int N=105;
 7 double dp[N][N];
 8 int v[N];
 9 int n,t;
10 int next(int p,int s)
11 {
12     p+=s;
13     if(p<=n)
14         return p;
15     else
16         return 2*n-p;
17 }
18 double dfs(int p,int k)
19 {
20     if(k>t)
21         return 0.0;
22     else if(p==n)
23         return 1.0;
24     else if(dp[p][k]>-eps)
25         return dp[p][k];
26     double ans=0;
27     for(int i=1;i<=6;i++)
28     {
29         int np=next(p,i);
30         if(v[np]==2)
31             ans+=dfs(0,k+1)/6.0;
32         else if(v[np]==1)
33             ans+=dfs(np,k+2)/6.0;
34         else
35             ans+=dfs(np,k+1)/6.0;
36     }
37     return dp[p][k]=ans;
38 }
39 int main()
40 {
41     int l,b;
42     while(scanf("%d%d%d%d",&n,&t,&l,&b),(n||t||l||b))
43     {
44         int tp;
45         memset(v,0,sizeof(v));
46         while(l--)
47         {
48             scanf("%d",&tp);
49             v[tp]=1;
50         }
51         while(b--)
52         {
53             scanf("%d",&tp);
54             v[tp]=2;
55         }
56         for(int i=0;i<=n;i++)
57             for(int j=0;j<=t;j++)
58                 dp[i][j]=-1;
59         printf("%.6lf\n",dfs(0,0));
60     }
61     return 0;
62 }