標籤:
高斯消元 求期望
題意:數軸上有0~n-1 個點,你每次可能走k步,1<=k<=m ,機率為Pk。起點和終點和初始方向都輸入。每次走到端點就轉向。求到達終點走過路程的期望。
解法:為了方便處理轉向,把n個點變成n=2*(n-2)個點。即0 1 2 3變成 0 1 2 3 2 1。確定好方向後,就可以直接列方程,設以pos為起點到達t經過的路程的期望為e[pos]。則有e[pos]=sigma(e[(pos+i)%k+i)*p[i] ,初始值顯然為e[t]=e[(n-t)%n]=0。然後高斯消元解方程組即可,矩陣為n*(n+1)的矩陣。
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <queue>#include <cmath>#define eps 1e-8#define INF 1e9using namespace std;double P[500] ;int vis[500] ;int n,m,y,x,d ,t ;double a[500][500] ;inline int sgn(double dd) { if (fabs(dd)<eps) return 0; return dd>0?1:-1;}bool bfs(int s){ queue <int> que ; que.push(s) ; memset(vis, 0, sizeof vis); vis[s] = 1; while(!que.empty()){ int d=que.front() ; que.pop() ; for(int i=1;i<=m;i++){ if(sgn(P[i])){ if(!vis[(d+i)%n]){ vis[(d+i)%n]=1; que.push((d+i)%n) ; } } } } if(vis[y] || vis[(n-y)%n]) return 1; return 0;}int gauss(int N, int M) { int i, j, r, c, pvt; double maxp; for (r=0, c=0; r<N && c<M; ++r, ++c) { for (maxp=0, i=r; i < N; ++i) if (fabs(a[i][c])>fabs(maxp)) maxp = a[pvt=i][c]; if (sgn(maxp)==0) { r--; continue; } if (pvt != r) for (j = r; j <= M; ++j) swap(a[r][j], a[pvt][j]); for (j = c+1; j <= M; ++j) { a[r][j] /= maxp; for (i = r+1; i < N; ++i) a[i][j] -= a[i][c]*a[r][j]; } } for (i = r; i < N; ++i) if (sgn(a[i][M])) return -1; if (r < M) return M-r; for (i = M-1; i >= 0; --i) for (j = i+1; j < M; ++j) a[i][M] -= a[j][M]*a[i][j]; return 0;}int main(){ scanf("%d",&t) ; while(t--){ memset(vis, 0 , sizeof vis) ; scanf("%d%d%d%d%d",&n,&m,&y,&x,&d); for(int i=1;i<=m;i++){ cin>>P[i] ; P[i]/=100; } n=(n-1) * 2; if(d>0) x=(n-x) % n; if(x==y){ printf("0.00\n"); continue ; } if(!bfs(x)){ printf("Impossible !\n") ; continue ; } //ап╥╫Ёл memset(a,0,sizeof a); double sum=0.0 ; for(int i=1;i<=m ; i++){ sum+=P[i]*i ; } for(int i=0;i<n;i++){ a[i][i]=1; if(!vis[i]){ a[i][n] = INF; continue ; } if(i==y || (n-y)%n == i){ a[i][n]=0.0 ; continue ; } a[i][n]=sum; int pos= i; for(int j=1;j<=m;j++){ pos=(pos+1)%n; a[i][pos]-=P[j]; } } if(!gauss(n,n)){ printf("%.2f\n",a[x][n]); } else printf("Impossible !\n"); } return 0;}
hdu 4418 Time travel