[CF9D]How Many Trees?_动态规划_树形dp_ntt
How many trees?
题目链接:https://www.codeforces.com/contest/9/problem/D
数据范围:略。
题解:
水题。
$f_{i,j}$表示$i$个节点,最大深度为$j$的方案,$g_{i,j}=\sum\limits_{k = 1}^{j - 1} f_{i, k}$。
显然,如果我们枚举深度的话,可以用$ntt$优化卷积。
这里写的$O(n^3)$。
代码:
#include <bits/stdc++.h>
#define setIO(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout)
#define N 2010
using namespace std;
typedef long long ll;
const int mod = 998244353 ;
int qpow(int x, int y) {
int ans = 1;
while (y) {
if (y & 1) {
ans = (ll)ans * x % mod;
}
y >>= 1;
x = (ll)x * x % mod;
}
return ans;
}
int f[N][N], g[N][N], a[N], b[N];
int main() {
// setIO("count");
int n, h;
cin >> n >> h ;
f[1][1] = 1;
g[0][0] = 1;
for (int dep = 1; dep <= n; dep ++ ) {
g[dep][0] = 1;
}
for (int dep = 2; dep <= n; dep ++ ) {
g[dep][1] = 1;
}
for (int dep = 2; dep <= n; dep ++ ) {
// for (int i = 1; i <= n; i ++ ) {
// a[i] = f[dep - 1][i], b[i] = g[dep - 1][i];
// }
// a * a + 2 * a * b
for (int l = 0; l <= n; l ++ ) {
for (int r = 0; r <= n; r ++ ) {
if (l + r + 1 <= n) {
(f[dep][l + r + 1] += (ll)f[dep - 1][l] * f[dep - 1][r] % mod) %= mod;
(f[dep][l + r + 1] += (ll)f[dep - 1][l] * g[dep - 1][r] % mod * 2 % mod) %= mod;
}
}
}
for (int i = 1; i <= n; i ++ ) {
g[dep][i] = (g[dep - 1][i] + f[dep - 1][i]) % mod;
}
// printf("Dep : %d\n", dep);
// for (int j = 1; j <= n; j ++ ) {
// printf("%d ", f[dep][j]);
// }
// puts("");
}
int ans = 0;
for (int i = h; i <= n; i ++ ) {
(ans +=
f[i][n]) %= mod;
}
cout << ans << endl ;
return 0;
}
| 欢迎来原网站坐坐! >原文链接<

浙公网安备 33010602011771号