给你一幅N*M的地图,地图中有不能到达的障碍物'#'与可以走的点'.',从(1,1)开始走到(N,M),其中每一次走动均等概率地向周围的可达的格子走去,求到达(N,M)的期望步数。(N,M<=10)

一开始根本不知道这题居然是用高斯消元来做的,感觉非常神奇,高斯消元作用就是你自己列出一系列关于期望的方程,然后求一个$E(1,1)$的变量值即可。

首先可以设每一个格子(X,Y)到达(N,M)的期望值为未知数$E(x,y)$,那么我们有N*M个格子,有N*M个未知数即N*M个变量,然后方程怎么列呢?可以发现每一个变量和周围的变量是存在关系的,由于是等概率地向周围移动,对于不可走的格子'#',显然$E(x,y)=0$;对于任意一个可以走的格子'.'坐标为(x,y),其四个方向中有k个方向是可行的,显然有:$E(x,y) =1+ \Sigma {{1 \over k}{E(x',y')}|(x',y')合法}$,比如当前点为(2,3),其中从(2,3)可以到达(2,4),(3,3),(1,3),假设(2,2)是'#'而不可到达(2,2),那么有$E(2,2)={1 \over 3}*E(2,4)+{1 \over 3}*E(3,3)+{1 \over 3}*E(1,3)+1$,两边同时乘以3再移项可以得到$3*E(2,2)-E(2,4)-E(3,3)-E(1,3)=3$,然后就可以得到很多个这样的等式,然后化成矩阵用高斯消元求解,其中答案就是E(1,1)这个点所对应的未知数的解

继昨天把j打成i死活没找到错误之后,今天又把m打成了n,又怀疑了一波人生,我可能用的是假键盘

代码:

#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 12;
const double eps = 1e-6; double Mat[N * N][N * N], ans[N * N];
int id[N][N];
int vis[N][N], dir[4][2] = {{1, 0}, {0, 1}, { -1, 0}, {0, -1}};
char pos[N][N];
int n, m; void init()
{
CLR(Mat, 0);
CLR(vis, 0);
CLR(ans, 0);
}
inline bool check(const int &x, const int &y)
{
return (x >= 1 && x <= n && y >= 1 && y <= m);
}
void dfs(int x, int y)
{
vis[x][y] = 1;
for (int i = 0; i < 4; ++i)
{
int vx = x + dir[i][0];
int vy = y + dir[i][1];
if (check(vx, vy) && !vis[vx][vy] && pos[vx][vy] == '.')
dfs(vx, vy);
}
}
int Gaussian(int ne, int nv)
{
int ce, cv, i, j;
// for (i = 1; i <= ne; ++i)
// for (j = 1; j <= nv + 1; ++j)
// printf("%.0f%c", Mat[i][j], "\t\n"[j == nv + 1]);
for (ce = 1, cv = 1; ce <= ne && cv <= nv; ++ce, ++cv)
{
int te = ce;
for (i = ce + 1; i <= ne; ++i)
if (fabs(Mat[i][cv]) > fabs(Mat[te][cv]))
te = i;
if (ce != te)
for (j = cv; j <= nv + 1; ++j)
swap(Mat[ce][j], Mat[te][j]);
double bas = Mat[ce][cv];
for (j = cv; j <= nv + 1; ++j)
Mat[ce][j] /= bas;
for (i = ce + 1; i <= ne; ++i)
for (j = cv + 1; j <= nv + 1; ++j)
Mat[i][j] -= Mat[i][cv] * Mat[ce][j];
}
for (i = ce; i >= 1; --i)
{
ans[i] = Mat[i][nv + 1];
for (j = i + 1; j <= nv; ++j)
ans[i] -= ans[j] * Mat[i][j];
ans[i] /= Mat[i][i];
}
return 1;
}
int main(void)
{
int i, j;
while (~scanf("%d%d", &n, &m))
{
init();
for (i = 1; i <= n; ++i)
{
scanf("%s", pos[i] + 1);
for (j = 1; j <= m; ++j)
id[i][j] = (i - 1) * m + j;
}
dfs(1, 1);
for (i = 1; i <= n; ++i)
{
for (j = 1; j <= m; ++j)
{
int I = id[i][j];
if ((i == n && j == m) || !vis[i][j])
{
Mat[I][I] = 1;
continue;
}
int cnt = 0;
for (int k = 0; k < 4; ++k)
{
int vi = i + dir[k][0];
int vj = j + dir[k][1];
if (check(vi, vj) && pos[vi][vj] == '.')
{
Mat[I][id[vi][vj]] = -1;
++cnt;
}
}
Mat[I][I] = cnt;
Mat[I][n * m + 1] = cnt;
}
}
Gaussian(n * m, n * m);
printf("%.8f\n", ans[1]);
}
return 0;
}
/*
10 10
..######.#
......#..#
.#.##.##.#
.#........
##.##.####
....#....#
.#######.#
....#.....
.####.####
....#..... 3 10
.#...#...#
.#.#.#.#.#
...#...#.. 2 3
.#.
...
*/

挑战程序竞赛例题 4.1 Random Walk(高斯消元求期望值)的更多相关文章

  1. 【高斯消元】兼 【期望dp】例题

    [总览] 高斯消元基本思想是将方程式的系数和常数化为矩阵,通过将矩阵通过行变换成为阶梯状(三角形),然后从小往上逐一求解. 如:$3X_1 + 2X_2 + 1X_3 = 3$ $           ...

  2. poj1182食物链_并查集_挑战程序设计竞赛例题

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 65534   Accepted: 19321 Description ...

  3. c实例_挑战程序竞赛,蚂蚁

    #include <stdio.h> //蚂蚁的题目 int max(int a,int b) { int count; count=a>b?a:b; return count; } ...

  4. 挑战程序竞赛 反转开关 poj3276

    这个我其实也没有看太懂它的证明过程. 1.若某一个位置被翻转了n次,则其实际上被翻转了n%2次. 2.分析易知翻转的顺序并不影响最终结果. 3.现在我们着眼于第1个位置,可知若要将第1个位置进行翻转只 ...

  5. 2017年中国大学生程序设计竞赛-中南地区赛暨第八届湘潭市大学生计算机程序设计大赛题解&源码(A.高斯消元,D,模拟,E,前缀和,F,LCS,H,Prim算法,I,胡搞,J,树状数组)

    A------------------------------------------------------------------------------------ 题目链接:http://20 ...

  6. 算法竞赛进阶指南0x35高斯消元与线性空间

    高斯消元 目录 高斯消元 ACWing207. 球形空间产生器(点击访问) 求解思路 代码 ACWing208. 开关问题(点击访问) 思路 代码 总结 欣赏 线性空间 定义 ACWing209. 装 ...

  7. HDU 4579 Random Walk (解方程组)

    Random Walk Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others)Total ...

  8. 【HDOJ】4579 Random Walk

    1. 题目描述一个人沿着一条长度为n个链行走,给出了每秒钟由i到j的概率($i,j \in [1,n]$).求从1开始走到n个时间的期望. 2. 基本思路显然是个DP.公式推导也相当容易.不妨设$dp ...

  9. 醉汉随机行走/随机漫步问题(Random Walk Randomized Algorithm Python)

    世界上有些问题看似是随机的(stochastic),没有规律可循,但很可能是人类还未发现和掌握这类事件的规律,所以说它们是随机发生的. 随机漫步(Random  Walk)是一种解决随机问题的方法,它 ...

随机推荐

  1. WQS二分学习笔记

    前言 \(WQS\)二分听起来是个很难的算法,其实学起来也并不是那么难. 适用范围 在某些题目中,会对于某个取得越多越优的物品,限定你最多选择\(k\)个,问你能得到的最优答案. 例如这道题目:[CF ...

  2. SqlServer2000事件探测器的使用

    由于公司自己开发的项目,需要与第三方软件数据库对接.我们项目用的数据库是MySQL而第三方用的是sqlserver2000.项目框架用的thinkphp5.0,通过thinkPHP新建一个模块,单独连 ...

  3. Cobbler自动安装的Linux系统ssh无法进入

    Linux ssh登陆老提示“permission denied,please try again” ,但是iptables已经关掉了 修改/etc/ssh/sshd_config文件.找如下的一句 ...

  4. 自建ssr(谷歌云免费试用一年)

    近期我一个朋友的VPN到期了,他也不想再去续费,同时发现谷歌云第一年申请时是免费的,所以他就自己搭建了一个自己专属的VPN 以下是他的搭建教程:  本教程难点在于申请免费试用资格 谷歌云+ssr搭建免 ...

  5. C# FileInfo 类

    FileInfo类不像File类,它没有静态方法,仅可用于实例化的对像.FileInfo对像表示在磁盘或网络位置的文件,注意它不是流,为了读写文件,必须创建Stream对像. fileInfo类提供了 ...

  6. .net core 获取浏览器UserAgent

    这两天由于自己公司的机器磁盘不够用了,果断把VS2015卸载了,只留下VS2017 当我打开一个以前一个很简单的MVC4.0的项目时候 温馨提示要安装MVC4,我犹豫了一下,还是点了安装,接下来提示要 ...

  7. JS大小转化B KB MB GB的转化方法

    function conver(limit){ var size = ""; ){ //如果小于0.1KB转化成B size = limit.toFixed() + "B ...

  8. 绘制弧形:imagearc() 说明:三点钟的位置是起点(0度

    <?php //1. 绘制图像资源(创建一个画布) $image = imagecreatetruecolor(500, 300); //2. 先分配一个绿色 $green = imagecol ...

  9. Liunx环境--Node部署记录

    1.看看环境里有没有装Node which node 2.找个目录安装 (1)/usr/local/node/download 执行下载 wget https://nodejs.org/dist/v8 ...

  10. 使用cxf 发布 jax-rs 风格webservice 。并客户端测试。

    详细介绍:http://www.ibm.com/developerworks/cn/java/j-lo-jaxrs/ 1.定义一个User对象 package com.zf.test; import  ...