Problem:
Score : 900 points

Problem Statement

Snuke loves permutations. He is making a permutation of length N.

Since he hates the integer K, his permutation will satisfy the following:

Let the permutation be a_1, a_2, ..., a_N. For each i = 1,2,...,N, |a_i - i| \neq K.

Among the N! permutations of length N, how many satisfies this condition?

Since the answer may be extremely large, find the answer modulo 924844033(prime).

Constraints

2 ≦ N ≦ 2000

1 ≦ K ≦ N-1

Input

The input is given from Standard Input in the following format:

N K

Output

Print the answer modulo 924844033.

Sample Input 1

3 1

Sample Output 1

2

2 permutations (1, 2, 3), (3, 2, 1) satisfy the condition.

Sample Input 2

4 1

Sample Output 2

5

5 permutations (1, 2, 3, 4), (1, 4, 3, 2), (3, 2, 1, 4), (3, 4, 1, 2), (4, 2, 3, 1) satisfy the condition.

Sample Input 3

4 2

Sample Output 3

9

Sample Input 4

4 3

Sample Output 4

14

Sample Input 5

425 48

Sample Output 5

756765083

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;

using i64 = long long;

const int N = 2048, MOD = 924844033;


i64 dp[N][N], knap[2][N], factorial[N];
bool f[N];

vector<int> chain_lens;
int n, k;


static void fix(i64 &x) {
	if (x >= MOD)
		x-= MOD;
	if (x < 0)
		x+= MOD; }

static void init_dp() {
	dp[0][0] = dp[1][0] = 1;

	for (int len = 2; len < N; ++len)
	for (int viol = 0; viol <= len / 2; ++viol) {
		dp[len][viol]+= dp[len - 1][viol];
		if (viol > 0)
			dp[len][viol]+= dp[len - 2][viol - 1];
		fix(dp[len][viol]); } }

int main() {
#ifdef HOME
	freopen("agc5d.in", "r", stdin);
	freopen("agc5d.out", "w", stdout);
#endif
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	i64 ant;
	int mx_dist;

	init_dp();

	cin >> n >> k;
	for (int l, t, i = 1; i <= n; ++i) if (!f[i]) {
		l = 1 + (i - k > 0);
		t = i;
		while (true) { // God forgive me
			f[t] = true;
			if (t + k <= n)
				l+= 1;
			if (t + 2 * k <= n) {
				l+= 1;
				t+= 2 * k; }
			else
				break; }

		chain_lens.push_back(l); }

	knap[0][0] = 1;
	mx_dist = 0;

	for (auto l: chain_lens) { // K steps (for each chain)
		for (int p = mx_dist; p >= 0; --p) // N (knapsack ptr)
			for (int step = 0; step <= l / 2; ++step) if(dp[l][step]) { // N / K (violation count)
				mx_dist = max(mx_dist, step + p);
				knap[1][p + step]+= knap[0][p] * dp[l][step] % MOD;
				fix(knap[1][p + step]); }

		swap(knap[0], knap[1]);
		memset(knap[1], 0x00, sizeof knap[1]); }

	factorial[0] = 1;
	for (int i = 1; i < N; ++i)
		factorial[i] = factorial[i - 1] * i % MOD;

	for (int i = 0; i <= n; ++i)
		knap[0][i] = knap[0][i] * factorial[n - i] % MOD;

	ant = 0;
	for (int i = 0; i <= n; i+= 2) {
		ant+= knap[0][i] - knap[0][i + 1];
		fix(ant);
		fix(ant); }

	cout << ant << endl;

	return 0; }