标签:
高斯消元 求期望
题意:数轴上有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 1e9 using 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; }
标签:
原文地址:http://www.cnblogs.com/Scale-the-heights/p/4703018.html