Problem:
Score : 600 points

Problem Statement

Let us define the oddness of a permutation p = {p_1,\ p_2,\ ...,\ p_n} of {1,\ 2,\ ...,\ n} as \sum_{i = 1}^n |i - p_i|.

Find the number of permutations of {1,\ 2,\ ...,\ n} of oddness k, modulo 10^9+7.

Constraints

All values in input are integers.

1 \leq n \leq 50

0 \leq k \leq n^2

Input

Input is given from Standard Input in the following format:

n k

Output

Print the number of permutations of {1,\ 2,\ ...,\ n} of oddness k, modulo 10^9+7.

Sample Input 1

3 2

Sample Output 1

2

There are six permutations of {1,\ 2,\ 3}. Among them, two have oddness of 2: {2,\ 1,\ 3} and {1,\ 3,\ 2}.

Sample Input 2

39 14

Sample Output 2

74764168

Solution in Kotlin (1.0.0) (judge verdict: Accepted)

fun main(args: Array<String>) {
    val mod = 1000000007L
    val (N, K) = readInputLine().split(" ").map { it.toInt() }
    val dp = Array(N + 1, {Array(N + 2, {LongArray(K + 2 * N + 1)})})
    
    dp[0][0][0] = 1
    
    for (i in 0 until N) {
        for (j in 0..N) {
            for (k in 0..K) {
                // pi = iとするケース dp[i + 1][j][k + 2 * j]にdp[i][j][k]を加算
                dp[i + 1][j][k + 2 * j] = (dp[i + 1][j][k + 2 * j] + dp[i][j][k]) % mod
                
                // iについて何もしないケース dp[i + 1][j + 1][k + 2 * j]にdp[i][j][k]を加算
                dp[i + 1][j + 1][k + 2 * j] = (dp[i + 1][j + 1][k + 2 * j] + dp[i][j][k]) % mod
                
                // iにこれまで使っていなかったpxを使うケース dp[i + 1][j][k + 2 * j]にdp[i][j][k] * jを加算(これまで使っていなかったpxの数分)
                dp[i + 1][j][k + 2 * j] = (dp[i + 1][j][k + 2 * j] + dp[i][j][k] * j % mod) % mod
                
                // x < iなるxにpiを使うケース dp[i + 1][j][k + 2 * j]にdp[i][j][k] * jを加算(これまで使っていなかったpxの数分)
                dp[i + 1][j][k + 2 * j] = (dp[i + 1][j][k + 2 * j] + dp[i][j][k] * j % mod) % mod
                
                // iにこれまで使っていなかったpxを使い、かつx < iなるxにpiを使うケース dp[i + 1][j - 1][k + 2 * j]にdp[i][j][k] * j * jを加算
                // ※1つ前と2つ前の合わせ技
                if (j > 0) {
                    dp[i + 1][j - 1][k + 2 * j] = (dp[i + 1][j - 1][k + 2 * j] + dp[i][j][k] * j % mod * j % mod) % mod
                }
            }
        }
    }
    
    println(dp[N][0][K])
}

fun readInputLine(): String {
    return readLine()!!
}