题解:
容斥,记
fi
f
i
表示有
i
i
个位置不满足的方案数,那么答案为
在 \mathchoicemodk \mathchoice mod k 意义下,相同的位置做 DP D P ,最后再背包合并即可得到 fi f i
#include <bits/stdc++.h>
using namespace std;
const int N=2e3+50,mod=924844033;
int n,k,dp[N][N][4],f[2][N],fac[N],ans;
inline int add(int x,int y) {return (x+y>=mod)?x+y-mod:x+y;}
inline int mul(int x,int y) {return (long long)x*y%mod;}
int main() {
cin>>n>>k; fac[0]=1;
for(int i=1;i<=n;i++) fac[i]=mul(fac[i-1],i);
for(int i=1;i<=n;i++) {
if(i<=k) {
dp[i][0][0]=1;
if(i+k<=n) dp[i][1][2]=1;
} else {
for(int j=0;j<=i && j<=n;j++) {
for(int s=0;s<=3;++s)
dp[i][j][s>>1]=add(dp[i][j][s>>1],dp[i-k][j][s]);
if(!j) continue;
dp[i][j][0]=add(dp[i][j][0],dp[i-k][j-1][0]);
dp[i][j][1]=add(dp[i][j][1],dp[i-k][j-1][2]);
if(i+k<=n) {
dp[i][j][2]=add(dp[i][j][2],dp[i-k][j-1][0]);
dp[i][j][2]=add(dp[i][j][2],dp[i-k][j-1][1]);
dp[i][j][3]=add(dp[i][j][3],dp[i-k][j-1][2]);
dp[i][j][3]=add(dp[i][j][3],dp[i-k][j-1][3]);
}
}
}
}
int now=0; f[now][0]=1;
for(int i=n;i>n-k && i;i--) {
now^=1;
for(int j=0;j<=n;j++) f[now][j]=0;
for(int j=0;j<=n/k+1;++j) {
int rs=0;
for(int s=0;s<=3;s++) rs=add(rs,dp[i][j][s]);
if(!rs) continue;
for(int k=n;k>=j;k--)
f[now][k]=add(f[now][k],mul(f[now^1][k-j],rs));
}
}
for(int i=0;i<=n;i++) {
if(i&1) ans=add(ans,mod-mul(f[now][i],fac[n-i]));
else ans=add(ans,mul(f[now][i],fac[n-i]));
}
printf("%d\n",ans);
}