高斯消元求期望!!
将n时间点构成2*(n-1)的环,每一点的期望值为dp[i]=dp[i+1]*p1+dp[i+2]*p2+……+dp[i+m]*pm+1.
这样就可以多个方程,利用高斯消元求解。
代码如下:
1 #include<iostream> 2 #include<stdio.h> 3 #include<algorithm> 4 #include<iomanip> 5 #include<cmath> 6 #include<cstring> 7 #include<vector> 8 #include<queue> 9 #define MAX 200 10 #define eps 1e-8 11 using namespace std; 12 double p[MAX],a[MAX][MAX],ans[MAX]; 13 int N,n,m,num[MAX],row,col,cnt; 14 int gauss() 15 { 16 int k,i,j; 17 for(i=0,j=0;i<row&&j<col;i++,j++){ 18 int m=i; 19 for(k=i+1;k<row;k++) 20 if(fabs(a[k][j])-fabs(a[m][j])>eps) 21 m=k; 22 if(fabs(a[m][j])<eps) return 0; 23 if(m!=i) 24 for(k=0;k<=col;k++) 25 swap(a[i][k],a[m][k]); 26 double aa=a[i][j]; 27 for(k=i+1;k<row;k++){ 28 double bb=a[k][j]/aa; 29 for(int l=j;l<=col;l++){ 30 a[k][l]-=bb*a[i][l]; 31 } 32 } 33 } 34 for(i=col-1;i>=0;i--){ 35 for(j=i+1;j<col;j++) 36 a[i][col]-=a[i][j]*ans[j]; 37 ans[i]=a[i][col]/a[i][i]; 38 } 39 return 1; 40 } 41 void bfs(int s) 42 { 43 queue<int>q; 44 memset(num,-1,sizeof(num)); 45 cnt=0; 46 num[s]=cnt++; 47 q.push(s); 48 while(!q.empty()){ 49 int t=q.front(); 50 q.pop(); 51 for(int i=1;i<=m;i++){ 52 if(fabs(p[i])<eps) continue; 53 int k=(i+t)%n; 54 if(num[k]==-1){ 55 num[k]=cnt++; 56 q.push(k); 57 } 58 } 59 } 60 } 61 int main(){ 62 int t,i,j,x,y,d,tm,k; 63 scanf("%d",&t); 64 while(t--){ 65 scanf("%d%d%d%d%d",&N,&m,&y,&x,&d); 66 for(i=1;i<=m;i++){ 67 scanf("%lf",&p[i]); 68 p[i]/=100.0; 69 } 70 if(x==y){ 71 printf("0.00\n"); 72 continue; 73 } 74 n=2*N-2; 75 if(d==1) x=n-x; 76 bfs(x); 77 if(num[y]==-1&&num[n-y]==-1){ 78 printf("Impossible !\n"); 79 continue; 80 } 81 memset(a,0,sizeof(a)); 82 memset(ans,0,sizeof(ans)); 83 row=col=cnt; 84 for(i=0;i<n;i++) 85 if(num[i]!=-1){ 86 a[num[i]][num[i]]=1; 87 if(i==y||i==n-y){ 88 ans[num[i]]=0; 89 continue; 90 } 91 for(j=1;j<=m;j++){ 92 tm=(i+j)%n; 93 if(num[tm]!=-1){ 94 a[num[i]][num[tm]]-=p[j]; 95 a[num[i]][cnt]+=j*p[j]; 96 } 97 } 98 } 99 if(gauss()) printf("%.2lf\n",ans[num[x]]); 100 else printf("Impossible !\n"); 101 } 102 return 0; 103 }