C++ 破解 4n - 1 结点二叉树优美 DFS 序数量问题:代码、解释与复杂度剖析
以下是解决此问题的 C++ 代码: ```cpp #include <iostream> #include <fstream> #include <vector> #define MOD 1000000007 using namespace std; const int MAXN = 1005; int n; vector<int> adj[MAXN * 4]; int leaf[MAXN * 4]; int dp[MAXN * 4][MAXN * 2][2]; // 深度优先搜索计算优美 DFS 序的数量 void dfs(int u) { if (u > 2 * n) { // 叶子节点 dp[u][0][0] = 1; return; } int l = adj[u][0], r = adj[u][1]; dfs(l); dfs(r); for (int i = 0; i <= n; i++) { for (int j = 0; j <= n; j++) { if (i + j > n) break; // 左子树在前 dp[u][i + j][0] = (dp[u][i + j][0] + 1LL * dp[l][i][0] * dp[r][j][0] % MOD) % MOD; dp[u][i + j][0] = (dp[u][i + j][0] + 1LL * dp[l][i][1] * dp[r][j][0] % MOD) % MOD; dp[u][i + j][0] = (dp[u][i + j][0] + 1LL * dp[l][i][0] * dp[r][j][1] % MOD) % MOD; dp[u][i + j][0] = (dp[u][i + j][0] + 1LL * dp[l][i][1] * dp[r][j][1] % MOD) % MOD; // 右子树在前 dp[u][i + j][1] = (dp[u][i + j][1] + 1LL * dp[r][j][0] * dp[l][i][0] % MOD) % MOD; dp[u][i + j][1] = (dp[u][i + j][1] + 1LL * dp[r][j][1] * dp[l][i][0] % MOD) % MOD; dp[u][i + j][1] = (dp[u][i + j][1] + 1LL * dp[r][j][0] * dp[l][i][1] % MOD) % MOD; dp[u][i + j][1] = (dp[u][i + j][1] + 1LL * dp[r][j][1] * dp[l][i][1] % MOD) % MOD; } } } int main() { ifstream fin("tree.in"); ofstream fout("tree.out"); int c; fin >> c; fin >> n; for (int i = 1; i <= 2 * n - 1; i++) { int l, r; fin >> l >> r; adj[i].push_back(l); adj[i].push_back(r); } for (int i = 1; i <= n; i++) { int a, b; fin >> a >> b; leaf[a] = leaf[b] = i; for (int j = 0; j <= 4 * n; j++) { for (int k = 0; k <= n; k++) { dp[j][k][0] = dp[j][k][1] = 0; } } dfs(1); fout << (dp[1][i][0] + dp[1][i][1]) % MOD << endl; } fin.close(); fout.close(); return 0; } ``` 代码解释: 1. 输入处理: - 从文件 `tree.in` 中读取测试点编号 `c` 和 `n`。 - 读取二叉树的结构,将每个非叶子节点的左右子节点存储在 `adj` 数组中。 - 读取每次操作选择的两个叶子节点,并将它们标记上相应的数字。 2. 动态规划数组: - `dp[u][i][0]` 表示以节点 `u` 为根的子树,包含 `i` 对相同数字的节点,且左子树在前的优美 DFS 序的数量。 - `dp[u][i][1]` 表示以节点 `u` 为根的子树,包含 `i` 对相同数字的节点,且右子树在前的优美 DFS 序的数量。 3. 深度优先搜索: - 对于叶子节点,初始化 `dp[u][0][0] = 1`。 - 对于非叶子节点,递归计算左右子树的 `dp` 值,然后根据左右子树的组合情况更新当前节点的 `dp` 值。 4. 输出结果: - 每次操作后,调用 `dfs(1)` 计算以根节点为根的子树的优美 DFS 序的数量,并将结果输出到文件 `tree.out` 中。 复杂度分析: - 时间复杂度:每次操作需要进行一次深度优先搜索,每次搜索的时间复杂度为 $O(n^2)$,因此总的时间复杂度为 $O(n^3)$。 - 空间复杂度:主要是 `dp` 数组的空间开销,为 $O(n^2)$。 ######[AI问答 | 1304点数解答 | 2026-02-07 20:35:12]
- C++ 破解 4n - 1 结点二叉树优美 DFS 序数量问题:代码、解释与复杂度剖析(字节豆包 | 1304点数解答 | 2026-02-07 20:35:12)32
- 易语言读取文本文件并显示到超级列表框:代码示例与注意要点(DeepSeek | 571点数解答 | 2025-08-23 20:54:40)247
- 易语言:读取并显示特定文本到超级列表框,还能增加新数据的方法与要点(DeepSeek | 1317点数解答 | 2025-08-23 20:58:40)246
- "Python代码:深度优先搜索判断马在棋盘上是否存在遍历路径"(GPT | 50点数解答 | 2024-11-18 19:36:52)236
- mallshop商城网站:数据库设计与强大业务功能全揭秘(GPT | 257点数解答 | 2024-12-09 14:08:15)284
- C++求解序列或与运算和差值:避O(nq)复杂度及数据处理要点(字节豆包 | 534点数解答 | 2025-10-17 20:05:07)68
- 探寻数组中最长摆动子序列长度:思路剖析与代码优化(GPT | 758点数解答 | 2024-12-23 23:18:29)282
- 独家剖析:求解数组最长摆动子序列长度的代码实现与改进建议(GPT | 350点数解答 | 2024-12-23 23:20:54)278
- 求解 1 至 n 内第 k 大孤独数:质数与余数的巧妙探寻(字节豆包 | 298点数解答 | 2025-11-10 20:01:57)177
- 巧判小朋友同桌意愿:满足需求还是无解难题?(字节豆包 | 599点数解答 | 2025-11-16 20:06:12)81
- 巧用代码判断:能否让 2n 个小朋友都拥有满意同桌?(字节豆包 | 445点数解答 | 2025-11-16 20:07:02)88
- 1000元存5年,哪种存款方式收益最高?答案惊人!(GPT | 1222点数解答 | 2024-11-13 18:03:09)186