You received as a gift a very clever robot walking on a rectangular board. Unfortunately, you understood that it is broken and behaves rather strangely (randomly). The board consists of N rows and M columns of cells. The robot is initially at some cell on the i-th row and the j-th column. Then at every step the robot could go to some another cell. The aim is to go to the bottommost (N-th) row. The robot can stay at it's current cell, move to the left, move to the right, or move to the cell below the current. If the robot is in the leftmost column it cannot move to the left, and if it is in the rightmost column it cannot move to the right. At every step all possible moves are equally probable. Return the expected number of step to reach the bottommost row.

Input

On the first line you will be given two space separated integers N and M (1 ≤ N, M ≤ 1000). On the second line you will be given another two space separated integers i and j (1 ≤ i ≤ N, 1 ≤ j ≤ M) — the number of the initial row and the number of the initial column. Note that, (1, 1) is the upper left corner of the board and (N, M) is the bottom right corner.

Output

Output the expected number of steps on a line of itself with at least 4 digits after the decimal point.

Examples

Input
10 10
10 4
Output
0.0000000000
Input
10 14
5 14
Output
18.0038068653

题意:一个N*M的矩阵,一个机器人站在x,y的位置,每次可以走四种:1.呆在原地 2.向下一步 3.向左一步 4.向右一步。问走到最后一行走的步数的期望是多少
题解:网上有许多高斯消元的方法,这道题也可以多次逼近写,直接推出转移方程。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<cmath>
#include<stack>
#include<cstdlib>
#include <vector>
#include<queue>
using namespace std; #define ll long long
#define llu unsigned long long
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
const int maxn = 1e5+5;
const int mod = 1e9+7; double f[1005][1005]; int main()
{
int N,M;
scanf("%d %d",&N,&M);
int x,y;
scanf("%d %d",&x,&y);
for(int i=N-1;i>=x;i--)
{
for(int k=1;k<=50;k++)
{
for(int j=1;j<=M;j++)
{
if(M == 1)
f[i][1] = (f[i][1] + f[i+1][1])/2 + 1;
else if(j == 1)
f[i][1] = (f[i][1] + f[i][2] + f[i+1][1])/3 + 1;
else if(j == M)
f[i][M] = (f[i][M] + f[i][M-1] + f[i+1][M])/3 + 1;
else
f[i][j] = (f[i][j-1] + f[i][j] + f[i][j+1] + f[i+1][j])/4 + 1;
}
}
}
printf("%lf\n",f[x][y]);
}

最新文章

  1. shell test用法
  2. Linux内核笔记——内存管理之块内存分配
  3. android app 内部文件路径
  4. winform(无边框窗体与timer)
  5. jQuery:show()方法
  6. Vcenter 添加域管理员权限
  7. Java API ——String类
  8. javaweb中去除某个get方式的参数,并且返回路径
  9. HDU 5737 Differencia(归并树)
  10. 为什么 1000 == 1000会返回false,100 == 100会返回true
  11. Python3学习笔记 - 准备环境
  12. [C#]设计模式-工厂方法-创建型模式
  13. ANN实现
  14. className.class.getResourceAsStream与ClassLoader.getSystemResourceAsStream区别
  15. AppImage格式安装包使用
  16. linux内核IDR机制详解【转】
  17. Linux学习笔记12—磁盘管理
  18. unity中制作模拟第一人称视角下的指南针
  19. robotium 中通过id获取 View 以及进行相应的操作
  20. CLR 关于强命名程序集 .

热门文章

  1. Unity C# 调用SaveFileDialog保存Excel文件
  2. MVC中 Remote的用法
  3. iOS多线程系统整理 swift
  4. HDU4352 XHXJ&#39;s LIS(LIS 状压)
  5. Apache Spark 2.2.0 中文文档 - GraphX Programming Guide | ApacheCN
  6. LeetCode Sort List 链表排序(规定 O(nlogn) )
  7. linux 命令——12 more (转)
  8. gearmand 编译 Unable to find libevent
  9. mac 远程桌面提示: 证书或相关链无效
  10. python_35_进度条