第二次做这道题还是不记得怎么做。。
考虑在分层图上跑dp。。
d
p
[
i
]
[
j
]
[
k
]
dp[i][j][k]
dp[i][j][k]表示在前
i
i
i层有
j
j
j个点,第
i
i
i层有
k
k
k个
转移方程:
i
<
K
:
d
p
[
i
]
[
j
]
[
k
]
=
d
p
[
i
−
1
]
[
j
−
k
]
[
x
]
×
C
n
−
j
+
k
−
1
k
×
(
2
x
−
1
)
k
×
2
k
(
k
−
1
)
2
i < K : dp[i][j][k] = dp[i - 1][j - k][x]\times C_{n-j+k-1}^k\times(2^x - 1)^k\times 2^{\frac{k(k-1)}{2}}
i<K:dp[i][j][k]=dp[i−1][j−k][x]×Cn−j+k−1k×(2x−1)k×22k(k−1)
i
=
K
:
d
p
[
i
]
[
j
]
[
k
]
=
d
p
[
i
−
1
]
[
j
−
k
]
[
x
]
×
C
n
−
j
+
k
−
1
k
−
1
×
(
2
x
−
1
)
k
×
2
k
(
k
−
1
)
2
i = K : dp[i][j][k] = dp[i - 1][j - k][x]\times C_{n-j+k-1}^{k-1}\times(2^x - 1)^k\times 2^{\frac{k(k-1)}{2}}
i=K:dp[i][j][k]=dp[i−1][j−k][x]×Cn−j+k−1k−1×(2x−1)k×22k(k−1)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define For(i, l, r) for (int i = (int)(l); i <= (int)(r); ++i)
#define Rep(i, r, l) for (int i = (int)(r); i >= (int)(l); --i)
#define Pb push_back
#define Mp make_pair
#define Fi first
#define Se second
#define Gc getchar
using namespace std;
typedef long long LL;
const int MOD = 1000000007;
const int INF = 0x3f3f3f3f;
const int N = 110;
int comp[N][N], dp[N][N][N], pow2[N * N];
inline void upd(int &x, int y) {x += y; x -= x >= MOD ? MOD : 0;}
inline int dec(int x, int y) {x -= y; x += x < 0 ? MOD : 0; return x;}
inline int add(int x, int y) {x += y; x -= x >= MOD ? MOD : 0; return x;}
inline int mul(int x, int y) {return 1LL * x * y % MOD;};
inline int qui_pow(int x, int y) {
int ret = 1;
for(; y; y >>= 1) {
if (y & 1) ret = mul(ret, x);
x = mul(x, x);
}
return ret;
}
inline void pre(int n) {
For(i, 0, n) comp[i][0] = 1;
For(i, 1, n) For(j, 1, i) comp[i][j] = add(comp[i - 1][j], comp[i - 1][j - 1]);
pow2[0] = 1;
For(i, 1, n * n) pow2[i] = mul(pow2[i - 1], 2);
}
inline LL read() {
LL x = 0, f = 1;
char ch = Gc();
while (!isdigit(ch) && ch != '-') ch = Gc();
if (ch == '-') f = -1, ch = Gc();
while (isdigit(ch)) {x = (x << 1) + (x << 3) + (ch ^ 48); ch = Gc();}
return x * f;
}
int main() {
int n = read(), K = read();
pre(n);
dp[0][1][1] = 1;
int ans = 0;
For(i, 1, K) For(j, i + 1, n - K + i) For(k, 1, j - i) {
LL now = i < K ? comp[n - j + k - 1][k] : comp[n - j + k - 1][k - 1];
For(x, 1, j - k - i + 1) upd(dp[i][j][k], mul(dp[i - 1][j - k][x], mul(now, mul(qui_pow(pow2[x] - 1, k), pow2[comp[k][2]]))));
if (i == K) upd(ans, mul(dp[i][j][k], pow2[k * (n - j) + comp[n - j][2]]));
}
printf("%d\n", ans);
return 0;
}