题意:在n*m的网格中,某个物体初始置于点(x,y),每一步行动都会等概率地停留在原地/往左/往右/往下走,求走到最后一行的的步数的数学期望,其中n,m<1000

lyd告诉我们这种题目要倒推处理.设\(f[i][j]\)为(i,j)到(n,k)的步数期望,k为任意数

那么对于各种边界有如下情况

\(f[n][j]=0\)

\(f[i][1]=\frac{1}{3}f[i][1]+\frac{1}{3}f[i][2]+\frac{1}{3}f[i+1][1]+1\)

\(f[i][m]=\frac{1}{3}f[i][m]+\frac{1}{3}f[i][m-1]+\frac{1}{3}f[i+1][m]+1\)

\(f[i][j]=\frac{1}{4}f[i][j]+\frac{1}{4}f[i][j-1]+\frac{1}{4}f[i][j+1]+\frac{1}{4}f[i+1][j]+1\)

式子2~4需要满足\(i<n\),式子4需要满足\(1<j<m\)

这种式子存在后效性,一种可行的方法是使用高斯消元处理,详见挑战程序设计竞赛P289 Random Walk

但以上方法仅适用于n*m<300左右的式子,这种需要手动消元才能在\(O(n*m)\)的时间内处理(其实硬上魔改应该也没问题?

首先要确认的是行内存在后效性,但行间无后效性,如果逆推的话就意味着在求解\(f[i][j]\)的时候\(f[i+1][j]\)是已知的,可作为常数处理

我们把常数项和未知数项分离

\(f[i][1]=(3+f[i+1][1])/2+\frac{1}{2}f[i][2]\)

\(f[i][1]=A+B*f[i][2],A=(3+f[i+1][1])/2,B=1/2\)

\(f[i][2]=(4+f[i][3]+f[i][1]+f[i+1][2])/3=(4+f[i][3]+A+B*f[i][2]+f[i+1][2])/3=(4+f[i][3]+A+f[i+1][2])/(3-B)\)

\(f[i][2]=(4+A+f[i+1][2])/(3-B)+\frac{1}{3-B}f[i][3]\)

\(f[i][2]=A'+B'*f[i][3],A'=(4+A+f[i+1][2])/(3-B),B'=1/(3-B)\)

以此类推直到

\(f[i][m-1]=A^{(m-1)}+B^{(m-1)}f[i][m]\)

又\(f[i][m]=(3+A^{(m-1)}+f[i+1][m])/(2-B^{(m-1)})\),该项可以初始化

通过逆推计算就可以得出全部项,而\(f[x][y]\)就是答案

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#define rep(i,j,k) for(register int i=j;i<=k;i++)
#define rrep(i,j,k) for(register int i=j;i>=k;i--)
#define erep(i,u) for(register int i=head[u];~i;i=nxt[i])
#define iter(i,j) for(int i=0;i<(j).size();i++)
#define print(a) printf("%lld",(ll)a)
#define println(a) printf("%lld\n",(ll)a)
#define printbk(a) printf("%lld ",(ll)a)
#define IOS ios::sync_with_stdio(0)
using namespace std;
const int MAXN = 1e3+11;
const int oo = 0x3f3f3f3f;
typedef long long ll;
const double EPS = 1e-8;
typedef vector<double> vec;
typedef vector<vec> mat;
ll read(){
ll x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,m;
double a[MAXN],b[MAXN],f[MAXN][MAXN];
int main(){
while(cin>>n>>m){
int x=read();
int y=read();
if(m==1){
printf("%.4lf\n",(double)(n-x)*2.0);
continue;
}
rep(i,0,m) f[n][i]=0;
rrep(i,n-1,1){
a[1]=(double)(3.0+f[i+1][1])/2.0;b[1]=0.5;
rep(j,2,m-1){
a[j]=(double)(4.0+a[j-1]+f[i+1][j])/(3.0-b[j-1]);
b[j]=(double)1.0/(3.0-b[j-1]);
}
f[i][m]=(double)(3.0+a[m-1]+f[i+1][m])/(2.0-b[m-1]);
rrep(j,m-1,1){
f[i][j]=a[j]+b[j]*f[i][j+1];
}
}
printf("%.10lf\n",f[x][y]);
}
return 0;
}

Codeforces - 24D 有后效性的DP处理的更多相关文章

  1. luogu 4042 有后效性的dp

    存在有后效性的dp,但转移方程 f[i] = min( f[i], s[i] + sigma f[j] ( j 是后效点) ) 每次建当前点和 转移点的边 e1, 某点和其会影响的点 e2 spfa ...

  2. CodeForces - 24D :Broken robot (DP+三对角矩阵高斯消元 随机)

    pro:给定N*M的矩阵,以及初始玩家位置. 规定玩家每次会等概率的向左走,向右走,向下走,原地不动,问走到最后一行的期望.保留4位小数. sol:可以列出方程,高斯消元即可,发现是三角矩阵,O(N* ...

  3. CodeForces 24D Broken robot (概率DP)

    D. Broken robot time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

  4. Luogu P2973 [USACO10HOL]赶小猪Driving Out the Piggi 后效性DP

    有后效性的DP:$f[u]$表示到$u$的期望次数,$f[u]=\Sigma_{(u,v)} (1-\frac{p}{q})*f[v]*deg[v]$,最后答案就是$f[u]*p/q$ 刚开始$f[1 ...

  5. Educational Codeforces Round 62 E 局部dp + 定义状态取消后效性

    https://codeforces.com/contest/1140/problem/E 局部dp + 定义状态取消后效性 题意 给你一个某些位置可以改变的字符串,假如字符串存在回文子串,那么这个字 ...

  6. poj 2228 Naptime(DP的后效性处理)

    \(Naptime\) \(solution:\) 这道题不做多讲,它和很多区间DP的套路一致,但是这一道题它不允许断环成链,会超时.但是我们发现如果这只奶牛跨夜休息那么它在不跨夜的二十四个小时里一定 ...

  7. Cogs 376. [IOI2002]任务安排(后效性DP)

    [IOI2002]任务安排 ★☆ 输入文件:batch.in 输出文件:batch.out 简单对比 时间限制:1 s 内存限制:128 MB N个任务排成一个序列在一台机器上等待完成(顺序不得改变) ...

  8. CF24D Broken robot 后效性DP

    这题咕了好久..... 设$f[i][j]$表示从$(i,j)$到最后一行的期望步数: 则有 $ f[i][1]=\frac{1}{3}(f[i][1]+f[i][2]+f[i+1][1])+1$ $ ...

  9. Makoto and a Blackboard CodeForces - 1097D (积性函数dp)

    大意: 初始一个数字$n$, 每次操作随机变为$n$的一个因子, 求$k$次操作后的期望值. 设$n$经过$k$次操作后期望为$f_k(n)$. 就有$f_0(n)=n$, $f_k(n)=\frac ...

随机推荐

  1. code1052 地鼠游戏

    贪心算法,从后往前 来自codevs的题解: 我的纠结思考过程:如果每一秒都没有重复的地鼠出现 那么肯定是一个一个挨着打如果有重复的地鼠 那么要考虑打那个更优 当然是选分值最大的 单纯这样想很合理 但 ...

  2. python算法 - 快速寻找满足条件的两个数-乾颐堂

    题目前提是一定存在这样两个数 解法一就不写了...一般想不到吧 一开始想到的是解法二最后的用hash表 (其实是想到创建一个跟target一样大的数组啦..存在就写入index,但是要全部找出,那得二 ...

  3. png 深度图像 转为 点云(opencv2)

    https://github.com/kruglov-dmitry/pnd2pcd_batch

  4. [原创]SOUI GDI+渲染引擎下的字体特效,抛砖引玉

    由于SOUI是一种双渲染引擎的DUI库,默认在SKIA渲染引擎下是支持特效字体的,具体请参考DEMO中的源码. 但是使用GDI+渲染时是没有这些特效的,着实比较苦恼,此代抛砖引玉,细节实现 请自己再去 ...

  5. ThreadLocal深入理解

    作者:知乎用户链接:https://www.zhihu.com/question/23089780/answer/62097840来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...

  6. 在Chrome 39中无法使用插件

    在chrome 42+版本中在开启npapi选项.   1.打开插件面板,在地址栏中输入 chrome://plugins   2.找到npScreenCapture插件,点击始终允许选框 3允许控件

  7. cenos7切换阿里源

    备份并安装base reop源 cd /etc/yum.repos.d sudo mv CentOS-Base.repo CentOS-Base.repo.bak 下载阿里源并配置 sudo wget ...

  8. eclipse配置tomcat 8.0.24服务器

    开发j2ee,肯定需要web容器来运行web项目,目前web容器有tomcat,jetty,Jboss,weblogic等服务器,最为常用的是tomcat服务器,其与eclipse的配置如下: tom ...

  9. MongoDB整理笔记のReplica Sets + Sharding

    MongoDB Auto-Sharding 解决了海量存储和动态扩容的问题,但离实际生产环境所需的高可靠.高可用还有些距离,所以有了"Replica Sets + Sharding" ...

  10. jQuery控制iframe框架内元素

    用jQuery在IFRAME里取得父窗口的某个元素的值只好用DOM方法与jquery方法结合的方式实现了 1.在父窗口中操作 选中IFRAME中的所有单选钮$(window.frames[" ...