《挑战》例题4.1 Random Walk
2015-10-20 14:50
246 查看
1.题目描述:有一个n*m的网格,从(0,0)出发,每一步可以朝着上下左右4个方向等概率地移动,另外一些格子中有石头,因此无法移动到这些格子,求第一次到达(n-1,m-1)格子的期望步数。可以保证至少存在一条从(0,0)到(n-1,m-1)的路径。
范围:2<=n,m<=10
样例:
Input
3 10
.#...#...#
.#.#.#.#.#
...#...#..
Output
361.00000000
2.解题思路:不妨设E(x,y)表示从(x,y)出发,到终点的期望步数,那么根据期望的线性性质和全期望公式,可以得到如下方程。
E(x,y)=0.25*E(x-1,y)+0.25*E(x+1,y)+0.25*E(x,y-1)+0.25*E(x,y+1)+1;
上述方程通过移项可以变成下式:
4*E(x,y)-E(x-1,y)-E(x+1,y)-E(x,y-1)-E(x,y+1)=4;
E(n-1,m-1)=0;
为了使得方程具有唯一解,我们令所有含有石头的格子和无法到达终点的格子都有E(x,y)=0。把这些方程联立,就可以求出最终的期望步数了。注意:建立矩阵的时候,要把二维先化成一维:(x,y)->x*m+y ,这样,便得到了一个n*m阶的系数矩阵。
3.代码:
范围:2<=n,m<=10
样例:
Input
3 10
.#...#...#
.#.#.#.#.#
...#...#..
Output
361.00000000
2.解题思路:不妨设E(x,y)表示从(x,y)出发,到终点的期望步数,那么根据期望的线性性质和全期望公式,可以得到如下方程。
E(x,y)=0.25*E(x-1,y)+0.25*E(x+1,y)+0.25*E(x,y-1)+0.25*E(x,y+1)+1;
上述方程通过移项可以变成下式:
4*E(x,y)-E(x-1,y)-E(x+1,y)-E(x,y-1)-E(x,y+1)=4;
E(n-1,m-1)=0;
为了使得方程具有唯一解,我们令所有含有石头的格子和无法到达终点的格子都有E(x,y)=0。把这些方程联立,就可以求出最终的期望步数了。注意:建立矩阵的时候,要把二维先化成一维:(x,y)->x*m+y ,这样,便得到了一个n*m阶的系数矩阵。
3.代码:
#include<iostream> #include<algorithm> #include<cassert> #include<string> #include<sstream> #include<set> #include<bitset> #include<vector> #include<stack> #include<map> #include<queue> #include<deque> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<cctype> #include<complex> #include<functional> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define rep(i,n) for(int i=0;i<(n);i++) #define me(s) memset(s,0,sizeof(s)) #define pb push_back #define lid (id<<1) #define rid (id<<1|1) typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> P; const int N=100+10; const double eps=1e-8; typedef double Matrix ; Matrix A; void gauss(int n) { int r; for(int i=0;i<n;i++) { r=i; for(int j=i+1;j<n;j++) if(fabs(A[j][i])>fabs(A[r][i]))r=j; if(r!=i)for(int j=0;j<=n;j++)swap(A[r][j],A[i][j]); for(int j=i+1;j<=n;j++) A[i][j]/=A[i][i]; A[i][i]=1.0; for(int k=0;k<n;k++) { if(fabs(A[k][i])<eps||k==i)continue; double f=A[k][i]; for(int j=0;j<=n;j++) A[k][j]-=f*A[i][j]; } } } char g ; int vis ; int n,m; int dx[]={-1,1,0,0}; int dy[]={0,0,-1,1}; bool inside(int x,int y){return x>=0&&x<n&&y>=0&&y<m;} void dfs(int x,int y) { vis[x][y]=1; for(int i=0;i<4;i++) { int nx=x+dx[i],ny=y+dy[i]; if(inside(nx,ny)&&g[nx][ny]!='#'&&!vis[nx][ny]) { dfs(nx,ny); } } } void solve() { me(A); me(vis); dfs(n-1,m-1); for(int i=0;i<n;i++) for(int j=0;j<m;j++) { if(i==n-1&&j==m-1||!vis[i][j]) { A[i*m+j][i*m+j]=1; continue; } int move=0; for(int k=0;k<4;k++) { int nx=i+dx[k],ny=j+dy[k]; if(inside(nx,ny)&&g[nx][ny]=='.') { A[i*m+j][nx*m+ny]=-1; move++; } } A[i*m+j][n*m]=A[i*m+j][i*m+j]=move; } gauss(n*m); } int main() { while(~scanf("%d%d",&n,&m)) { rep(i,n)scanf("%s",g[i]); solve(); printf("%.10lf\n",A[0][n*m]); } }
相关文章推荐
- Matlab 高斯消元
- 高斯消元
- [BZOJ1013][JSOI2008][高斯消元]球形空间产生器sphere
- poj 1222 高斯消元
- hdu 4418 高斯消元+概率dp
- BZOJ4031——HEOI小z的房间
- poj 1681 Painter's Problem 高斯消元
- poj 1830 开关问题 高斯消元
- 高斯消元
- HDU 4870 Rating 多校联合练习赛 高斯消元
- POJ 1830 开关问题 (高斯消元)
- POJ 1753 Flip Game (高斯消元)
- POJ 3185 The Water Bowls(高斯消元)
- POJ 1681 Painter's Problem (高斯消元)
- SGU 275 To xor or not to xor (高斯消元)
- SGU 200 Cracking RSA (高斯消元+大数高精度)
- HDU 3976 Electric resistance (高斯消元)
- poj 1487 Single-Player Games 高斯消元
- poj 1222 EXTENDED LIGHTS OUT 高斯消元
- poj 1753 Flip Game 高斯消元