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 ...
随机推荐
- python中fork()函数生成子进程分析-乾颐堂
python的os module中有fork()函数用于生成子进程,生成的子进程是父进程的镜像,但是它们有各自的地址空间,子进程复制一份父进程内存给自己,两个进程之 间的执行是相互独立的,其执行顺序可 ...
- 空值和null区别
空值代表杯子是真空的,NULL代表杯子中装满了空气
- revert
git revert是用一次新的commit来回滚之前的commit
- C primer 编程练习 (不断更新)
目前在看<C Primer>,以后会经常在这篇博客里更新课后的编程练习题 第二章:编程练习 2.1 #include <stdio.h> int main(void) { pr ...
- 手动添加ceph的mds
1.在需要安装的目标机器上创建mds目录 mkdir -p / 2.生成mds的keyring,并将其写入/var/lib/ceph/mds/ceph-0/keyring文件中 ceph auth g ...
- HDU 6127 Hard challenge (极角扫描)
题意:给定 n 个点,和权值,他们两两相连,每条边的权值就是他们两个点权值的乘积,任意两点之间的直线不经过原点,让你从原点划一条直线,使得经过的直线的权值和最大. 析:直接进行极角扫描,从水平,然后旋 ...
- java上转型之instanceof--避免引用类型强制转化出错
Object obj="hello"; 上面的obj是什么类型? object?NO!String?NO? 答案:编译阶段是Object类型,而在运行阶段是String类型.实际上 ...
- jenkins构建后接受者收不到邮件问题解决方案
jenkins部署.安装增强版邮件插件,配置邮件及增强版邮件通知请参考网上教程,由于教程比较多页通俗易懂,笔者在这里不做重复说明,本文重点是解决配置好增强版邮件,job构建后仍然收不到邮件的问题 步骤 ...
- NIOS II下基于中断的UART接收和发送设计示例代码
#include "sys/alt_stdio.h" #include "altera_avalon_uart_regs.h" #include "s ...
- Web开发入门经典:使用PHP6、Apache和MySQL 中文pdf扫描版
通过学习本书,读者很快就能明白为什么PHP.Apache和MySQL会迅速成为开发动态网站最流行的方式,本书将为读者理解这3个核心组件如何独立工作和协同工作奠定良好的基础,引导读者充分利用它们提供的各 ...