一道莫名其妙的黑题
这道题其实我开始的思路是容斥的,然而我写的容斥减去了一些重复的部分
导致最后的答案很奇怪
然后就换换思路
ans[i][j]表示i对情侣中有j对和睦的方案数
考虑ans[i][j]的转移,那么可以得出
表示i对情侣中选j对情侣的方案数,乘上在i排座位里选j排座位的方案数,乘上这j对情侣坐j排座位的方案数
,乘上每对情侣各有两种做法的方案数,而其他的i-j对情侣都没有和睦的方案数
对于ans[i][0]就比较特殊
然后就可以做出来了
贴上代码
#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
int c[1005][1005],n,fac[2005],t,two[2005],ans[1005][1005];
inline int moc(int x)
{
if(x>=mod) return x-mod;
if(x<0) return x+mod;
return x;
}
int main()
{
for(register int i=0;i<=1000;i++)
{
c[i][0]=1;
for(register int j=1;j<=i;j++)
{
c[i][j]=moc(c[i-1][j-1]+c[i-1][j]);
}
}
fac[0]=1;
for(int i=1;i<=2000;i++)
fac[i]=1ll*fac[i-1]*i%mod;
two[0]=1;
for(int i=1;i<=2000;i++)
two[i]=moc(two[i-1]<<1);
ans[0][0]=1;
for(int i=1;i<=1000;i++)
{
for(int j=1;j<=i;j++)
ans[i][j]=1ll*c[i][j]*c[i][j]%mod*fac[j]%mod*two[j]%mod*ans[i-j][0]%mod,ans[i][0]=moc(ans[i][0]-ans[i][j]);
ans[i][0]=moc(fac[i+i]+ans[i][0]);
}
cin>>t;
while(t--)
{
scanf("%d",&n);
for(int i=0;i<=n;i++)
printf("%d\n",ans[n][i]);
}
return 0;
}
/*
1 3
*/