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 C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+10,mod=1e9+7;
void plusle(int &a,int b){
    a+=b;if(a>=mod)a-=mod; return;
}
void minun(int &a,int b){
    a-=b; if(a<0)a+=mod; return;
}
int add(int a,int b) {
  a+=b;
  return a>=mod?a-mod:a;
}
int sub(int a,int b) {
  a-=b;
  return a<0?a+mod:a;
}
int mul(int a,int b) {
  return (int)((long long)a*b%mod);
}
int dp[2][51][2501],n,k;

int main(){
    scanf("%d%d",&n,&k);
    dp[0][0][0]=1;
    int x=0;
    /**
    This is the most weird dp problem I've seen so far
    But require some good insight
    dp[i][j][k] is the number of ways to match 
    from 1,..i-th such that there is j elements pending to be matched with i+1 or later
    until it's paired with something it will increase the oddness 1 in each step
    One key is: the number of unmatched left side and right side is equal
    */
    for(int i=1;i<=n;i++){
        x^=1;
        memset(dp[x],0,sizeof(dp[x]));
        for(int j=0;j<=n;j++){
            for(int l=2*j;l<=k;l++){
                plusle(dp[x][j][l],mul(2*j+1,dp[x^1][j][l-2*j]));
                if(j<n)
                plusle(dp[x][j][l],mul((j+1)*(j+1),dp[x^1][j+1][l-2*j]));
                if(j>0)
                plusle(dp[x][j][l],dp[x^1][j-1][l-2*j]);
            }
        }
    }
    printf("%d\n",dp[x][0][k]);
/*
|i-p[i]|
*/
}
/*
    Good Luck
        -Lucina
*/