[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; }
| 欢迎来原网站坐坐! >原文链接<