[HDU 4418] Time travel

题目:给出一个长度为n的数轴和一个初始方向,一个人一次可以走[1,m]步,走到头就会自动反弹回来,求给定起点X到Y的期望步数

E[x]表示x点到终点的期望,则E[x]=sigma(E[x+i]+i),E[Y]=0

因为还有方向问题,所以我们把n个点拆成2*n-2个,原数轴01234变成01234321

即一个点表示沿固定方向到Y的期望

然后高斯消元解方程

n=1时需要特判

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define eps 1e-12//
 4 #define maxn 205
 5 int T,N,M,X,Y,D,F,A[maxn],vis[maxn],q[maxn];
 6 double ans[maxn],fnc[maxn][maxn],p[maxn];
 7 bool eq(double x,double y){ return fabs(x-y)<eps; }
 8 bool judge(int s){
 9     int head=0,tail=0;
10     F=0,memset(vis,-1,sizeof(vis));
11     vis[q[++tail]=s]=F++;
12     while(head<tail){
13         int u=q[++head];
14         for(int i=1;i<=M;i++){
15             if(eq(p[i],0))continue;
16             int v=(u+i)%(2*N-2);//go die
17             if(vis[v]==-1)vis[q[++tail]=v]=F++;
18         }
19     }
20     return vis[Y]!=-1||vis[2*N-2-Y]!=-1;
21 }
22 void build(){
23     memset(fnc,0,sizeof(fnc));
24     for(int i=0;i<2*N-2;i++){
25         if(vis[i]==-1)continue;
26         fnc[vis[i]][vis[i]]=1; 
27         if(A[i]==Y)continue;
28         int u=vis[i];
29         for(int j=1;j<=M;j++){
30             int v=vis[(i+j)%(2*N-2)];
31             if(v==-1)continue;
32             fnc[u][v]-=p[j];
33             fnc[u][F]+=j*p[j];
34         }
35     }
36 }
37 bool guass(){
38     build();
39     int cur=0,nxt;
40     for(int i=0;i<F;i++){
41         for(nxt=cur;nxt<F;nxt++)
42             if(!eq(fnc[nxt][i],0))break;
43         if(nxt==F)continue;
44         if(nxt!=cur){
45             for(int j=0;j<=F;j++)
46                 swap(fnc[cur][j],fnc[nxt][j]);
47         }
48         for(int j=cur+1;j<F;j++)
49             if(!eq(fnc[j][i],0)){
50                 double val=fnc[j][i]/fnc[cur][i];
51                 for(int k=i;k<=F;k++)
52                     fnc[j][k]-=val*fnc[cur][k];
53             }
54         cur++;
55     }
56     for(int i=cur;i<F;i++)
57         if(!eq(fnc[i][F],0))return false;
58     for(int i=0;i<2*N-2;i++)ans[i]=-1;
59     for(int i=cur-1;i>=0;i--){
60         double res=fnc[i][F];
61         for(int j=F-1;j>=i;j--)
62             if(!eq(fnc[i][j],0)){//
63                 if(eq(ans[j],-1))ans[j]=res/fnc[i][j];
64                 res-=ans[j]*fnc[i][j];
65             }
66     }
67     return true;
68 }
69 int main(){
70     scanf("%d",&T);
71     while(T--){
72         scanf("%d%d%d%d%d",&N,&M,&Y,&X,&D);
73         for(int i=1;i<=M;i++)
74             scanf("%lf",&p[i]),p[i]/=100;
75         if(N==1)printf("%.2lf
",0.0);
76         else{
77             int s;
78             if(D==1)s=2*N-2-X;
79             else s=X;
80             for(int i=0;i<N;i++)A[i]=i;
81             for(int i=1;i<N-1;i++)A[2*N-2-i]=A[i];
82             if(!judge(s))puts("Impossible !");//
83             else if(!guass())puts("Impossible !");
84             else printf("%.2lf
",ans[vis[s]]);
85         }
86     }
87     return 0;
88 }
View Code
原文地址:https://www.cnblogs.com/Ngshily/p/5519497.html