题解
- 考虑一下dp
- 设f[i]为大小为i的联通块的个数,h[i]为大小为i的图的个数
- 其实转移状态很显然


- 可以设dp[i][j]为大小为i的图的个数,j=1有联通块等于k,j=0所有联通块小于k
- 状态转移方程为

代码
1 #include <cstdio>
2 #include <iostream>
3 #define N 2010
4 #define mo 998244353
5 using namespace std;
6 int n,k;
7 long long mi[N*N],f[N][2],F[N],g[N],c[N][N];
8 int main()
9 {
10 scanf("%d%d",&n,&k);
11 mi[0]=1; for (int i=1;i<=n*n;i++) mi[i]=mi[i-1]*2%mo;
12 c[0][0]=1;
13 for (int i=1;i<=n;i++)
14 {
15 c[i][0]=1;
16 for (int j=1;j<=i;j++) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mo;
17 }
18 F[1]=0,g[1]=1;
19 for (int i=2;i<=n;i++)
20 {
21 for (int j=1;j<=i-1;j++) F[i]=(F[i]+g[j]*(g[i-j]+F[i-j])%mo*c[i-1][j-1]%mo)%mo;
22 g[i]=(mi[i*(i-1)/2]-F[i]+mo)%mo;
23 }
24 memset(f,0,sizeof(f)),f[0][0]=1;
25 for (int i=1;i<=n;i++)
26 for (int j=1;j<=k;j++)
27 if (i-j>=0)
28 for (int z=0;z<=1;z++)
29 f[i][z|(j==k)]=(f[i][z|(j==k)]+f[i-j][z]*g[j]%mo*c[i-1][j-1]%mo)%mo;
30 printf("%lld",f[n][1]);
31 }