Problem:
E: Entangled with Lottery

ICPC で良い成績を収めるには修行が欠かせない．うさぎは ICPC で勝ちたいので，今日も修行をすることにした．

今日の修行は，あみだくじを利用して，未来を読む力をつけて運気を高めようというものである．もちろん直感に頼るだけでなく，綿密な確率計算も欠かせない．

今回考えるあみだくじは，長さ H + 1 センチメートルの縦棒 N 本からなる．うさぎは棒の上部を見て，N 本のうち 1 本を選ぶことになる．棒の下部には，左から P 本目の棒の場所にのみ「当たり」と書かれている．あみだくじにはいくつかの横棒が含まれる．横棒の配置に関して，以下の条件を考えよう．

各横棒は，a を 1 以上 H 以下の整数として，縦棒の上端から a センチメートルの高さにある．

各横棒は，隣り合った 2 本の縦棒のみを結ぶ．

同じ高さには複数の横棒は存在しない．

うさぎはこれらの条件を満たすように M 本の横棒を引いた．あいにくうさぎは記憶力が良いので，当たりの位置や横棒の位置をすべて覚えてしまっており，あみだくじを楽しめない．そこで友達のねこにさらに横棒を追加してもらうことにした．

まず，うさぎは当たりを狙って N 本の棒のうち 1 本を選ぶ．その後，ねこは以下の操作をちょうど K 回行う．

横棒を追加しても上で指定された条件を満たすような場所のうち 1 箇所を無作為に選ぶ．ここで，どの場所も等確率で選ばれるものとする．選んだ場所に横棒を追加する．

そして，うさぎが選んだ棒が当たりであったかを判定する．棒の辿り方は通常のあみだくじと同様である (横棒に出会うたびに隣の縦棒に移る)．うさぎは，可能な限り当たりとなる確率を高くしたい．

Input

H N P M K
A1 B1
...
AM BM

Ai, Bi (1 ≤ i ≤ M) はうさぎが引いた横棒のうち i 番目のものが，縦棒の上端から Ai センチメートルの高さにあり，左から Bi 本目の縦棒と左から Bi + 1 本目の縦棒を結ぶことを表す整数である．

2 ≤ H ≤ 500，2 ≤ N ≤ 100，1 ≤ P ≤ N，1 ≤ M ≤ 100，1 ≤ K ≤ 100，M + K ≤ H，1 ≤ A1 < A2 < ... < AM ≤ H，1 ≤ Bi ≤ N - 1 を満たす．

Output

当たりとなる確率が最大となるようにうさぎが棒を選んだときの，当たりとなる確率を 1 行に出力せよ．10-6 以下の絶対誤差が許容される．

Sample Input 1

9 4 3 2 1
2 1
7 3

Sample Output 1

0.571428571

Sample Input 2

9 4 3 2 3
2 1
7 3

Sample Output 2

0.375661376

Solution in C++ (judge verdict: Accepted)

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>

using namespace std;

const double EPS=1e-10;
bool EQ(double a,double b){
  return abs(a-b)<EPS;
}

double dp[511][111][111];
int H,N,P,M,K;
bool A[511];
bool B[511][111][111];
//double cnt;

double dfs(int i,int j,int k,double cnt){
  if(dp[i][j][k]>=-0.5)return dp[i][j][k];
  if(i==H+1){
    // kは使い切っていなくても到達確率には問題ない？
    if(j==P&&k==0)return 1;
    return 0;
  }
  double res=0;
  // この高さに線が存在
  if(A[i]!=0){
    // 左へ移動
    if(j!=0&&B[i][j-1][j])
      res=dfs(i+1,j-1,k,cnt);
    // 右へ移動
    else if(j+1!=N&&B[i][j][j+1])
      res=dfs(i+1,j+1,k,cnt);
    // 移動なし
    else res=dfs(i+1,j,k,cnt);
  }
  else{
    if(k>=1){
      if(j+1!=N&&j!=0){
	// to left
	res+=dfs(i+1,j-1,k-1,cnt-1)*(k/cnt)*(1.0/(N-1));
	// to right
	res+=dfs(i+1,j+1,k-1,cnt-1)*(k/cnt)*(1.0/(N-1));
	// no move without bar
	if(cnt-k!=0)
	  res+=dfs(i+1,j,k,cnt-1)*((1.0*cnt-k)/cnt);
	// no move with bar
	res+=dfs(i+1,j,k-1,cnt-1)*(k/cnt)*(1.0*(N-3)/(N-1));
      }
      else if(j!=0){
	// to left
	res+=dfs(i+1,j-1,k-1,cnt-1)*(k/cnt)*(1.0/(N-1));
	// no move without bar
	if(cnt-k!=0)
	  res+=(dfs(i+1,j,k,cnt-1))*(1.0*cnt-k)/cnt;
	// no move with bar
	res+=dfs(i+1,j,k-1,cnt-1)*(k/cnt)*(1.0*(N-2)/(N-1));
      }
      else if(j+1!=N){
	// to right
	res+=dfs(i+1,j+1,k-1,cnt-1)*(k/cnt)*(1.0/(N-1));
	// no move without bar
	if(cnt-k!=0)
	  res+=(dfs(i+1,j,k,cnt-1))*(1.0*cnt-k)/cnt;
	// no move with bar
	res+=dfs(i+1,j,k-1,cnt-1)*(k/cnt)*(1.0*(N-2)/(N-1));
      }
    }
    else{
      // no move
      res+=dfs(i+1,j,k,cnt);
    }
  }
  return dp[i][j][k]=res;
}

int main(){

  while(cin>>H>>N>>P>>M>>K&&(H|N|P|M|K)){
    P--; 
    double cnt=H;
    memset(A,0,sizeof(A));
    memset(B,0,sizeof(B));
    for(int i=0;i<511;i++)
      for(int j=0;j<111;j++)
	for(int k=0;k<111;k++)dp[i][j][k]=-1;
    int a,b;
    for(int i=0;i<M;i++){
      cnt--;
      cin>>a>>b;
      A[a]=true;
      b--;
      B[a][b][b+1]=true;
      B[a][b+1][b]=true;
    }
    double res=0;
    for(int i=0;i<N;i++){
      if(!EQ(res,dfs(1,i,K,cnt))&&res<dfs(1,i,K,cnt))
	res=dfs(1,i,K,cnt);
    }
    printf("%.10f\n",res);
  }
  

  return 0;
}