light oj 1151 - Snakes and Ladders 高斯消元+概率DP

思路:

在没有梯子与蛇的时候很容易想到如下公式:

dp[i]=1+(∑dp[i+j])/6

但是现在有梯子和蛇也是一样的,初始化p[i]=i;

当有梯子或蛇时转移为p[a]=b;

这样方程变为:

dp[i]=1+(∑dp[p[i+j]])/6

再就是注意当i+j>100时,停在原地不变。

代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define M 105
 7 #define eps 1e-6
 8 using namespace std;
 9 double ans[M],an[M][M];
10 int p[M];
11 void GAUSS()
12 {
13     int i,j,t,k;
14     for(i=1;i<=100;i++){
15         t=i;
16         for(j=i+1;j<=100;j++)
17             if(an[t][i]<an[j][i]) t=j;
18         if(t!=i){
19             for(j=1;j<=101;j++)
20                 swap(an[i][j],an[t][j]);
21         }
22         if(fabs(an[i][i])<eps) continue;
23         for(j=i+1;j<=100;j++){
24             if(fabs(an[j][i])>eps){
25                 double tt=an[j][i]/an[i][i];
26                 for(k=i;k<=101;k++)
27                     an[j][k]=an[j][k]-an[i][k]*tt;
28             }
29         }
30     }
31     for(i=100;i>=1;i--){
32         for(j=100;j>i;j--){
33             an[i][101]-=an[i][j]*ans[j];
34         }
35         if(fabs(an[i][i])>eps)
36             ans[i]=an[i][101]/an[i][i];
37         if(fabs(ans[i])<eps) ans[i]=0.0;
38     }
39 }
40 void solve()
41 {
42     memset(ans,0,sizeof(ans));
43     memset(an,0,sizeof(an));
44     for(int i=1;i<=100;i++){
45         an[i][i]=an[i][101]=6.0;
46         for(int j=1;j<=6;j++){
47             if(i+j>100) an[i][i]-=1.0;
48             else an[i][p[i+j]]+=-1.0; //感开始没有+,一直错啊…………
49         }
50     }
51     GAUSS();
52 }
53 int main()
54 {
55     int t,ca=0,n,m,a,b;
56     scanf("%d",&t);
57     while(t--){
58         scanf("%d",&n);
59         for(int i=1;i<=100;i++) p[i]=i;
60         for(int i=0;i<n;i++){
61             scanf("%d %d",&a,&b);
62             p[a]=b;
63         }
64         solve();
65         printf("Case %d: %.8lf\n",++ca,ans[1]);
66     }
67     return 0;
68 }
View Code

 

 

 

 

posted @ 2013-10-03 19:34  _随心所欲_  阅读(380)  评论(0编辑  收藏  举报