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 ...
随机推荐
- CentOS7 下 安装 supervisor
[注] linux环境必须安装 python 1.获取supervisor包:[https://pypi.python.org/pypi/supervisor] # wget https://pypi ...
- 【转】C++中#if #ifdef 的作用
一般情况下,源程序中所有的行都参加编译.但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是“条件 编译”.有时,希望当满足某条件时对一组语句进行编译,而当 ...
- QT学习之窗口部件
对话框--QDialog 模态对话框与非模态对话框 模态对话框:就是相当于没关闭它之前,不能再和该应用程序的其他窗口进行交互(比如新建项目时弹出的对话框) 非模态对话框:可以与它交互,也可以与该程序中 ...
- Windows 配置 nginx php 多版本切换
1. 下载 nginx nginx.org 2. 下载 php windows.php.net 选择 nts 版本,解压后,将php.ini.development 重命名为 php.in ...
- 6、Semantic-UI之动画按钮样式
6.1 动画按钮样式 在Semantic-UI中提供了三种动画样按钮式表,分别为: 左右移动 上下移动 淡入淡出 在实际开发中,很少使用这种动画按钮,根据实际情况使用,强制使用到页面中反而不太适合 ...
- python文件操作os模块
Python 统计某一文件夹下文件数量 使用python pathlib模块 from pathlib import Path dir_path = ' ' print(len(list(Path( ...
- memcached整理の内存管理及删除机制
内存的碎片化 如果用C语言直接malloc,free来向操作系统申请和释放内存时,在不断申请和释放的过程中,形成了一些很小的内存片段,无法再利用.这种空闲但无法利用内存的现象称为内存的碎片化. sla ...
- Git SSH Key
一.设置Git的user name和email: $ git config --global user.name "hhl_vip" $ git config --global ...
- 「HNOI 2013」比赛
题目链接 戳我 \(Solution\) 这道题观察数据范围发现很小,再看看题目可以发现是搜索. 这题纯搜索会\(T\)所以要加入适当剪枝 如果一个人后面的比赛都赢却依旧到不了目标分数,则直接\(re ...
- JComboBox组件的列表实时更新
JComboBox deleteUser = new JComboBox(queryUser()); //queryUser()的返回值为字符串数组 deleteUser.setModel(new D ...