Codeforces - 24D 有后效性的DP处理
题意:在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处理的更多相关文章
- luogu 4042 有后效性的dp
存在有后效性的dp,但转移方程 f[i] = min( f[i], s[i] + sigma f[j] ( j 是后效点) ) 每次建当前点和 转移点的边 e1, 某点和其会影响的点 e2 spfa ...
- CodeForces - 24D :Broken robot (DP+三对角矩阵高斯消元 随机)
pro:给定N*M的矩阵,以及初始玩家位置. 规定玩家每次会等概率的向左走,向右走,向下走,原地不动,问走到最后一行的期望.保留4位小数. sol:可以列出方程,高斯消元即可,发现是三角矩阵,O(N* ...
- CodeForces 24D Broken robot (概率DP)
D. Broken robot time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...
- 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 ...
- Educational Codeforces Round 62 E 局部dp + 定义状态取消后效性
https://codeforces.com/contest/1140/problem/E 局部dp + 定义状态取消后效性 题意 给你一个某些位置可以改变的字符串,假如字符串存在回文子串,那么这个字 ...
- poj 2228 Naptime(DP的后效性处理)
\(Naptime\) \(solution:\) 这道题不做多讲,它和很多区间DP的套路一致,但是这一道题它不允许断环成链,会超时.但是我们发现如果这只奶牛跨夜休息那么它在不跨夜的二十四个小时里一定 ...
- Cogs 376. [IOI2002]任务安排(后效性DP)
[IOI2002]任务安排 ★☆ 输入文件:batch.in 输出文件:batch.out 简单对比 时间限制:1 s 内存限制:128 MB N个任务排成一个序列在一台机器上等待完成(顺序不得改变) ...
- 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$ $ ...
- Makoto and a Blackboard CodeForces - 1097D (积性函数dp)
大意: 初始一个数字$n$, 每次操作随机变为$n$的一个因子, 求$k$次操作后的期望值. 设$n$经过$k$次操作后期望为$f_k(n)$. 就有$f_0(n)=n$, $f_k(n)=\frac ...
随机推荐
- Inno Setup创建快捷方式跟快速运行栏快捷方式
[Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescrip ...
- How to add a date range picker to filter for dates on a GridView for Yii2 - See more at: http://www.2amigos.us/blog/how-to-add-a-date-range-picker-to-filter-for-dates-on-a-gridview-for-yii2#sthash.pf7
Filtering the data we have on our GridView by dates are sometimes very important. On this article I ...
- CentOS下的Git服务器
[Gitosis]CentOS下的Git服务器:Gitosis [摘要] 详细介绍如何在CentOS上配置Gitosis 我们很多人知道Git可能是从Github开始的 ...
- 编写高质量代码改善C#程序的157个建议——建议81:使用Parallel简化同步状态下Task的使用
建议81:使用Parallel简化同步状态下Task的使用 在命名空间System.Threading.Tasks中,有一个静态类Parallel简化了在同步状态下的Task的操作.Parallel主 ...
- Android测试入门篇
Android本身是一套软件堆叠(Software Stack),或者成为软件叠层架构,叠层主要分成三层:操作系统.中间件和应用程序. Android构架 1. Application 应用程序层:用 ...
- Grunt 与WebStrom 集成
为了不想使用命令行的方式开着grunt,打算将Grunt命令集成WebStrom 中 . 1.将配置好的Gruntfile文件放到项目的根目录下.. 2.File-setting-Extental T ...
- JS 前端构建工具gulpjs的使用介绍及技巧
gulpjs是一个前端构建工具,与gruntjs相比,gulpjs无需写一大堆繁杂的配置参数,API也非常简单,学习起来很容易,而且gulpjs使用的是nodejs中stream来读取和操作数据,其速 ...
- Intel GPA果然是神器
又一次PERF暗黑三...只有GPA帮到了我. Intel GPA是一个用于测试产品性能和质量的工具.使用这个工具可以运行在游戏或3D应用程序中用来看看它们是如何工作的,其优势性的一点是,有了Auto ...
- replaceState 实现返回从新定位
在web 开发中,选择列表分类,在中商品, 详情页面后,返回的时候我们想定位到原来选择的分类 就需要借助window.history.replaceState来实现 function getProdu ...
- Hadoop 文件命令
* 文件操作 * 查看目录文件 * $ hadoop dfs -ls /user/cl * * 创建文件目录 * $ hadoop dfs -mkdir /user/cl/temp * * 删除文件 ...