题目链接:

http://ac.jobdu.com/problem.php?pid=1546

题目意思:

有一个起点S,多个出口E,#代表不能走,每次等概率的随机选择下一个可以行走的位置,求从S到出口的期望。

解题思路:

高斯消元求解期望。

先BFS预处理能够到达的出口的位置,然后如果从起点不能到达终点,直接输出-1.

然后对于无效的点,置该未知数的解为-1,否则依据dp[i][j]=1+dp[i-1][j]*1/4+dp[i][j+1]*1/4+dp[i+1][j]*1/4+dp[i][j-1]*1/4,构建n*m个方程,注意有些位置的可行位置数小于4,为cnt的话,此时的下一步概率为1/cnt.

然后解方程,求出唯一解。

PS:

解方程时,如果有的未知数有解,有的无解,可以将无解的情况置一个特殊值,然后按有唯一解的方式来解方程,避免无解未知数对有解未知数的影响。

方程系数要清零。wa了好几次。

代码:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#define eps 1e-8
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std; #define Maxn 20 char sa[Maxn][Maxn];
int n,m,num,dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
double dp[Maxn][Maxn],pp[Maxn][Maxn];
double g[Maxn*Maxn][Maxn*Maxn],ans[Maxn*Maxn];
bool vis[Maxn][Maxn]; void gaosi(int r,int c)
{
for(int i=0,j=0;i<r&&j<c;i++,j++)
{
int t=i;
for(int p=i+1;p<=r;p++)
if(fabs(g[p][j])>fabs(g[t][j]))
t=p;
if(fabs(g[t][j])<eps) //这是多解的情况
continue;
if(t-i) //不相同,则交换
{
for(int p=j;p<=c;p++)
swap(g[t][p],g[i][p]);
}
for(int p=i+1;p<=r;p++)
{
double tmp=g[p][j]/g[i][j];
if(fabs(tmp)<eps)
continue;
g[p][j]=0.0;
for(int q=j+1;q<=c;q++)
g[p][q]-=tmp*g[i][q];
}
}
for(int p=r;p>=0;p--)
{
if(fabs(g[p][p])<eps) //无解的情况
continue;
ans[p]=g[p][c];
for(int q=r;q>p;q--)
ans[p]-=g[p][q]*ans[q];
ans[p]/=g[p][p];
}
}
bool iscan(int x,int y)
{
if(x<0||x>=n||y<0||y>=m)
return false;
return true;
}
int sx,sy; bool bfs() //从S出发找到所有可行的位置
{
bool flag=false;
queue<pair<int,int> >myq;
myq.push(make_pair(sx,sy));
memset(vis,false,sizeof(vis));
vis[sx][sy]=true; while(!myq.empty())
{
int x=myq.front().first;
int y=myq.front().second; myq.pop();
for(int i=0;i<4;i++)
{
int ans=x+dir[i][0],yy=y+dir[i][1];
if(!iscan(ans,yy)||vis[ans][yy]||sa[ans][yy]=='#')
continue;
vis[ans][yy]=true;
myq.push(make_pair(ans,yy));
if(sa[ans][yy]=='E') //能够到达终点
flag=true;
}
}
return flag;
}
double dl(double a)
{
if(fabs(a)<eps)
return 0;
return a;
} int main()
{
while(~scanf("%d%d",&n,&m))
{
int ss; for(int i=0;i<n;i++)
{
scanf("%s",sa[i]);
for(int j=0;j<m;j++)
{
if(sa[i][j]=='S')
{
sx=i,sy=j;
ss=i*m+j;
}
}
}
if(!bfs()) //不能够到达终点
{
printf("-1\n");
continue;
}
num=-1;
int last=n*m; memset(g,0,sizeof(g));
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
num++;
int tmp=i*m+j;
if(!vis[i][j]) //无解的位置
{
g[num][tmp]=1;
g[num][last]=-1;
}
else
{
if(sa[i][j]=='E') //终点位置
{
g[num][tmp]=1;
g[num][last]=0;
continue;
}
int cnt=0,next[5];
for(int k=0;k<4;k++) //求出下一步可行的位置数
{
int x=i+dir[k][0],y=j+dir[k][1];
if(iscan(x,y)&&sa[x][y]!='#'&&vis[x][y])
{
cnt++;
next[cnt]=x*m+y;
}
}
g[num][tmp]=1;
g[num][last]=1;
for(int k=1;k<=cnt;k++) //构建当前位置的方程
g[num][next[k]]=-1.0/(cnt*1.0);
}
}
gaosi(n*m-1,n*m);
ans[ss]=dl(ans[ss]);
if(ans[ss]>0)
printf("%.2f\n",ans[ss]);
else
printf("-1\n");
}
return 0;
}

概率dp-九度-1546-迷宫问题的更多相关文章

  1. 九度 1537:买卖股票(区间DP)

    总结 1. 更新动规矩阵时, 不要 push 更新, 要用 pull更新. push 更新容易让逻辑出问题, 自己卡了很久, 改用 pull 就变得很顺利了 2. acm 题, 空间至多是百万, 再网 ...

  2. 九度 1547 出入栈(递推DP)

    题目描述: 给定一个初始为空的栈,和n个操作组成的操作序列,每个操作只可能是出栈或者入栈.要求在操作序列的执行过程中不会出现非法的操作,即不会在空栈时执行出栈操作,同时保证当操作序列完成后,栈恰好为一 ...

  3. 九度OJ 1337:寻找最长合法括号序列 (DP)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:839 解决:179 题目描述: 给你一个长度为N的,由'('和')'组成的括号序列,你能找出这个序列中最长的合法括号子序列么?合法括号序列的 ...

  4. 【整理】简单的数学期望和概率DP

    数学期望 P=Σ每一种状态*对应的概率. 因为不可能枚举完所有的状态,有时也不可能枚举完,比如抛硬币,有可能一直是正面,etc.在没有接触数学期望时看到数学期望的题可能会觉得很阔怕(因为我高中就是这么 ...

  5. 【剑指Offer面试编程题】题目1360:乐透之猜数游戏--九度OJ

    题目描述: 六一儿童节到了,YZ买了很多丰厚的礼品,准备奖励给JOBDU里辛劳的员工.为了增添一点趣味性,他还准备了一些不同类型的骰子,打算以掷骰子猜数字的方式发放奖品.例如,有的骰子有6个点数(点数 ...

  6. [转]概率DP总结 by kuangbin

    概率类题目一直比较弱,准备把kuangbin大师傅总结的这篇题刷一下! 我把下面的代码换成了自己的代码! 原文地址:http://www.cnblogs.com/kuangbin/archive/20 ...

  7. SGU 422 Fast Typing(概率DP)

    题目大意 某人在打字机上打一个字符串,给出了他打每个字符出错的概率 q[i]. 打一个字符需要单位1的时间,删除一个字符也需要单位1的时间.在任意时刻,他可以花 t 的时间检查整个打出来的字符串,并且 ...

  8. HYSBZ 1415 - 聪聪和可可(概率DP)

    http://vjudge.net/problem/viewProblem.action?id=20613 题意:不用说了,中文题. 这个题可以用概率DP来做. 题中要求猫抓到老鼠的时间期望.分析一下 ...

  9. poj 2096 Collecting Bugs (概率dp 天数期望)

    题目链接 题意: 一个人受雇于某公司要找出某个软件的bugs和subcomponents,这个软件一共有n个bugs和s个subcomponents,每次他都能同时随机发现1个bug和1个subcom ...

  10. 九度OJ 1500 出操队形 -- 动态规划(最长上升子序列)

    题目地址:http://ac.jobdu.com/problem.php?pid=1500 题目描述: 在读高中的时候,每天早上学校都要组织全校的师生进行跑步来锻炼身体,每当出操令吹响时,大家就开始往 ...

随机推荐

  1. python3 读写excel

    一直认为python3可以很快的实现很多简单的功能,今天要读excel表格数据,想来很简单,网上一搜,用xlrd即可,然后很多人给出了不同的版本,号称xlrd3,实际上官网一看,xlrd0.9.4兼容 ...

  2. 我摘录的js代码

    1.修改样式 document.getElementByIdx( "div1").style.display = "none"; 2.鼠标悬停图标变小手 sty ...

  3. VS2010 release 和 debug 调试区别

    VC下Debug和Release区别 最近写代码过程中,发现 Debug 下运行正常,Release 下就会出现问题,百思不得其解,而Release 下又无法进行调试,于是只能采用printf方式逐步 ...

  4. php开发环境安装配置(1)

    个人记录高手请勿喷! 下载xampp我这是个中文版的可以自己搜索下载安装别的版本也行. 双击下载的xampp会提示路径相当于解压到指定的路径 到对应路径去可看到如下: 打开 2.配置: 成功之后会如下 ...

  5. 转:GraphicsMagick介绍及安装

    原文来自于:http://www.cnblogs.com/cocowool/archive/2010/08/16/1800954.html GraphicsMagick 当前稳定版本:1.3.12(发 ...

  6. House Of Hello恶搞包为什么如此受热捧!

    凤凰时尚    在大多数人的心中,奢侈品都是昂贵的,摆在精美的橱窗中,动辄上万的价格,高贵而冷艳,也让很多人望而却步.然而,最近在很多时尚年轻一族中却流传着这样一句话“昂贵不等于奢侈,奢侈是一种生活态 ...

  7. crf 分词(待)

    http://blog.csdn.net/marising/article/details/5769653

  8. JavaScript----Performance Tool and Process

    1. Syntax-------------JSLint, JSHint, 2. Combine------------YUI 3. Minify---------------JSMin

  9. SharePoint 2013 WebTemplates

    SharePoint 2013 WebTemplates You are here: Home / SharePoint 2013 WebTemplates   January 24, 2013 Ta ...

  10. codeforces C. Restore Graph

    题意:构造一个有n个顶点,每个点度不超过k,然后给出每一个点到达一个定点的最短距离d数组,然后构造出这样的一个图: 思路:排序之后,有两个距离为0的或者没有直接输出-1,然后用两个游动下表,后面的与前 ...