Problem:
Score: 400 points

Problem Statement

Amidakuji is a traditional method of lottery in Japan.

To make an amidakuji, we first draw W parallel vertical lines, and then draw horizontal lines that connect them. The length of each vertical line is H+1 [cm], and the endpoints of the horizontal lines must be at 1, 2, 3, ..., or H [cm] from the top of a vertical line.

A valid amidakuji is an amidakuji that satisfies the following conditions:

No two horizontal lines share an endpoint.

The two endpoints of each horizontal lines must be at the same height.

A horizontal line must connect adjacent vertical lines.

Find the number of the valid amidakuji that satisfy the following condition, modulo 1\ 000\ 000\ 007: if we trace the path from the top of the leftmost vertical line to the bottom, always following horizontal lines when we encounter them, we reach the bottom of the K-th vertical line from the left.

For example, in the following amidakuji, we will reach the bottom of the fourth vertical line from the left.

Constraints

H is an integer between 1 and 100 (inclusive).

W is an integer between 1 and 8 (inclusive).

K is an integer between 1 and W (inclusive).

Input

Input is given from Standard Input in the following format:

H W K

Output

Print the number of the amidakuji that satisfy the condition, modulo 1\ 000\ 000\ 007.

Sample Input 1

1 3 2

Sample Output 1

1

Only the following one amidakuji satisfies the condition:

Sample Input 2

1 3 1

Sample Output 2

2

Only the following two amidakuji satisfy the condition:

Sample Input 3

2 3 3

Sample Output 3

1

Only the following one amidakuji satisfies the condition:

Sample Input 4

2 3 1

Sample Output 4

5

Only the following five amidakuji satisfy the condition:

Sample Input 5

7 1 1

Sample Output 5

1

As there is only one vertical line, we cannot draw any horizontal lines. Thus, there is only one amidakuji that satisfies the condition: the amidakuji with no horizontal lines.

Sample Input 6

15 8 5

Sample Output 6

437760187

Be sure to print the answer modulo 1\ 000\ 000\ 007.

Solution in Rust (1.15.1) (judge verdict: Accepted)

use std::vec::Vec;

fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>().split_whitespace().map(|e| e.parse().ok().unwrap()).collect()
}

fn read_touple<T: std::str::FromStr + Copy>() -> (T, T, T) {
  let v: Vec<T> = read_vec();
  assert_eq!(v.len(), 3);
  (v[0], v[1], v[2])
}

const MOD: usize = 1_000_000_000 + 7;
fn main() {
    let (H, W, K) = read_touple::<usize>();
    let bits = BitSet::empty(W-1);
    let mut dp = vec![vec![0; W+1]; H+1];


    // init 
    dp[0][0] = 1;

    for i in 0..H {
      for j in 0..W {
        for b in bits {
          if !check(b) {
             continue
          }
          //println!("{:?}", b);

          if 0 < j && j < W-1 {
             if b.include(j-1) {
                dp[i+1][j] += dp[i][j-1];
                dp[i+1][j] %= MOD;
             }
             if !b.include(j-1) && !b.include(j) {
                dp[i+1][j] += dp[i][j];
                dp[i+1][j] %= MOD;
             }
             if b.include(j) {
                dp[i+1][j] += dp[i][j+1];
                dp[i+1][j] %= MOD;
             }
          } else if j == 0 {
             if b.include(j) {
                dp[i+1][j] += dp[i][j+1];
                dp[i+1][j] %= MOD;
             } else {
               dp[i+1][j] += dp[i][j];
               dp[i+1][j] %= MOD;
             }
          } else if j == W-1 {
            if b.include(j-1) {
               dp[i+1][j] += dp[i][j-1];
               dp[i+1][j] %= MOD;
            }
            if !b.include(j-1) {
               dp[i+1][j] += dp[i][j];
               dp[i+1][j] %= MOD;
            }
          }
        }
        // for i in 0..H+1 {
        //   println!("{:?}", dp[i]);
        // }
        // println!("");
      }
    }
    // for i in 0..H+1 {
    //   println!("{:?}", dp[i]);
    // }

    println!("{}", dp[H][K-1] % MOD);
}

fn check(bits: BitSet) -> bool {
  let biv = bits.to_vec();
  let n = biv.len();
  if n == 0 {
     return true;
  }
  for i in 0..n-1  {
    if biv[i] == 1 && biv[i+1] == 1 {
       return false;
    }
  }
  true
}

#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
struct BitSet {
    bits: usize,
    size: usize,
}

impl std::fmt::Debug for BitSet {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "BitSet {{ bits: {:b}, size: {} }}", self.bits, self.size)
    }
}

impl BitSet {
    //
    fn empty(size: usize) -> BitSet {
        if size > 64 {
            panic!("large set size")
        }
        BitSet {
            bits: 0,
            size: size,
        }
    }
    // コンンストラクター
    fn new(n: usize, size: usize) -> BitSet {
        BitSet {
            bits: n,
            size: size,
        }
    }

    // 和集合を求める
    fn union(&self, other: BitSet) -> BitSet {
        BitSet {
            bits: self.bits | other.bits,
            size: self.size, // debug
        }
    }

    // 共通部分を求める
    fn intersect(&self, other: BitSet) -> BitSet {
        BitSet {
            bits: self.bits & other.bits,
            size: self.size, // debug
        }
    }

    // n を含むかどうか
    fn include(&self, n: usize) -> bool {
        if self.size < n {
            return false;
        }
        self.bits & (1 << n) != 0
    }

    fn to_vec(&self) -> std::vec::Vec<usize> {
        let mut res = std::vec::Vec::new();
        let mut bits = self.bits;

        for _ in 0..self.size {
            res.push(bits % 2);
            bits /= 2;
        }
        res
    }

    // 集合を表すusizeの値を返す
    fn unwrap(&self) -> usize {
        self.bits
    }
}

impl Iterator for BitSet {
    type Item = BitSet;

    fn next(&mut self) -> Option<Self::Item> {
        if (1 << self.size) <= self.bits {
            return None;
        }
        self.bits += 1;
        Some(BitSet {
            bits: self.bits-1,
            size: self.size,
        })
    }
}