尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

P2014 [CTSC1997] 选课

P2014 [CTSC1997] 选课
📅 发布时间:2026/6/18 18:08:21

P2014 [CTSC1997] 选课

大意

有些学科 \(i\) 有先修课 \(fa\) 这些课程形成了一个树形结构,问选 \(m\) 门课所能达到的最大的学分。

思路

考虑树上背包。

我们定义 \(f_{u,j}\) 表示在 \(u\) 子树内选 \(j\) 门课的最大学分,类似我们的背包,我们采用倒序枚举,保证转移的正确性。

枚举 \(j\),表示 \(u\) 这颗子树选 \(j,j \in [m, 0]]\) 个,再枚举 \(k\) 表示在子树 \(v\) 中选 \(k(k \in [0, j))\) 个,显然有转移方程:

\[f_{u, j} = \max(f_{u,j}, f_{u,j - k} + f_{v, k}) \]

然后就是重要的上下界优化了,刚刚的代码时间复杂度在大概 \(\mathcal{O}(nm^2)\) 的,但是很多情况没必要去考虑。

首先就是我们的 \(j\),你要想选几个得看 \(sz_u\),于是我们就可以将 \(j\) 的上界定为 \(\min(sz_u, m)\),下界就是 \(0\),不需要改动。

接着就是 \(k\) 的枚举,若你在子树 \(u\) 内选了 \(j\) 个,那么如果在子树 \(v\) 之外的点有 \(sz_u - sz_v\) 个,而为了选 \(j\) 个,我们在 \(v\) 内只是至少要选 \(j - (sz_u - sz_v)\) 个才可能保证能选出 \(j\) 个,上界和刚刚同理,为 \(\min(j - 1, sz_v)\)。

经过这样的优化,可以得出复杂度为 \(\mathcal{O}(nm)\)。

证明如下:

1. 符号定义

符号 数学定义
\(n\) 树的节点总数
\(\text{child}(u)\) 节点\(u\)的所有子节点构成的集合
\(\text{siz}(u)\) 以\(u\)为根的子树包含的节点数量(子树大小)
\(T(u)\) 处理以\(u\)为根的子树所需的总时间
\(t(u)\) 合并\(u\)的所有子树、处理节点\(u\)本身的时间(不含子树递归处理时间)
\(m\) 背包容量(问题中最多选择的节点数,枚举范围受\(m\)约束)

2. 无背包容量约束时的\(O(n^2)\)复杂度证明

2.1 总时间的递归表达式

处理子树\(u\)的总时间等于其所有子节点子树的处理时间之和,加上合并子树的时间:

\[T(u) = \sum_{v \in \text{child}(u)} T(v) + t(u) \]

2.2 合并时间\(t(u)\)的化简

设 \(\text{child}(u) = \{v_1, v_2, \dots, v_k\}\),合并子树时的时间\(t(u)\)满足:

\[t(u) = 1 + \sum_{i=1}^{|\text{child}(u)|} \left(1 + \sum_{j=1}^i \text{siz}(v_j)\right) \cdot \text{siz}(v_i) \]

由子树大小的定义 \(\text{siz}(u) = 1 + \sum_{v \in \text{child}(u)} \text{siz}(v)\),可化简得:

\[t(u) = O\left(\text{siz}(u)^2\right) \]

2.3 归纳法证明\(T(u) = O(\text{siz}(u)^2)\)
  • 基例(叶子节点):
    若 \(u\) 为叶子节点,则 \(\text{child}(u) = \emptyset\),此时:

    \[T(u) = t(u) = 1 = O(1^2) = O(\text{siz}(u)^2) \]

  • 归纳步:
    假设对 \(\forall v \in \text{child}(u)\),均有 \(T(v) = O(\text{siz}(v)^2)\),则:

    \[\sum_{v \in \text{child}(u)} T(v) = O\left(\sum_{v \in \text{child}(u)} \text{siz}(v)^2\right) \]

    由平方和不等式 \(\sum_{v \in \text{child}(u)} \text{siz}(v)^2 \leq \left(\sum_{v \in \text{child}(u)} \text{siz}(v)\right)^2 = (\text{siz}(u)-1)^2\),得:

    \[\sum_{v \in \text{child}(u)} T(v) = O\left(\text{siz}(u)^2\right) \]

    结合 \(t(u) = O(\text{siz}(u)^2)\),最终有:

    \[T(u) = O\left(\text{siz}(u)^2\right) \]

2.4 全局复杂度

遍历所有节点求和,树的所有子树大小的平方和满足 \(\sum_{u} \text{siz}(u)^2 = O(n^2)\),因此:

\[\sum_{u} T(u) = O\left(\sum_{u} \text{siz}(u)^2\right) = O(n^2) \]

3. 加入背包容量\(m\)后的\(O(nm)\)复杂度证明

3.1 合并时间\(t(u)\)的修正(加入\(m\)约束)

背包容量限制枚举范围,\(t(u)\) 修正为:

\[t(u) = 1 + \sum_{i=1}^{|\text{child}(u)|} \min\left(m, 1 + \sum_{j=1}^i \text{siz}(v_j)\right) \cdot \min\left(m, \text{siz}(v_i)\right) \]

化简得:

\[t(u) = O\left(\min(\text{siz}(u), m) \cdot \text{siz}(u)\right) \]

3.2 分情况推导\(T(u)\)
  • 情况1:\(\text{siz}(u) \leq m\)
    此时 \(\min(\text{siz}(u), m) = \text{siz}(u)\),故:

    \[T(u) = O\left(\text{siz}(u)^2\right) \]

  • 情况2:\(\text{siz}(u) > m\)
    将\(\text{child}(u)\)分为两类:

    \[S_1 = \{v \in \text{child}(u) \mid \text{siz}(v) \leq m\}, \quad S_2 = \{v \in \text{child}(u) \mid \text{siz}(v) > m\} \]

    对两类子节点分别求和:

    \[\sum_{v \in S_1} T(v) = O\left(\left(\sum_{v \in S_1} \text{siz}(v)\right)^2\right) = O(m^2) \]

    \[\sum_{v \in S_2} T(v) = O\left(m \cdot \sum_{v \in S_2} \text{siz}(v)\right) \]

    结合 \(t(u) = O(m \cdot \text{siz}(u))\),最终得:

    \[T(u) = O\left(m \cdot \text{siz}(u)\right) \]

3.3 全局复杂度

遍历所有节点求和,结合 \(\min(\text{siz}(u), m) \cdot \text{siz}(u)\) 的上界约束:

\[\sum_{u} T(u) = O\left(\sum_{u} \min(\text{siz}(u), m) \cdot \text{siz}(u)\right) = O(nm) \]

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 310;
vector<int> g[N];
int f[N][N], n, m, siz[N];
void dfs(int u) {siz[u] = 1;for (int i = 0; i < g[u].size(); i++) {int v = g[u][i];dfs(v);siz[u] += siz[v];for (int j = min(m, siz[u]); j >= 0; --j) {for (int k = max(1, j - siz[u] + siz[v]); k <= min(j - 1, siz[v]); ++k) {f[u][j] = max(f[u][j], f[u][j - k] + f[v][k]);}}}
}
int main() {cin >> n >> m;m++;for (int i = 1; i <= n; ++i) {int fa, val;cin >> fa >> val;g[fa].push_back(i);f[i][1] = val;}dfs(0);cout << f[0][m];return 0;
}

本文来自一名高中生,作者:To_Carpe_Diem

相关新闻

  • 彻底讲清 MySQL InnoDB 锁机制:从 Record 到 Next-Key 的全景理解
  • MCU的启动流程你了解么?
  • I2C通信最全面的讲解:从协议到硬件设计

最新新闻

  • 2026 年北京离婚律师专业实力推荐榜:家事纠纷维权选型客观评测报告 - 信息热点
  • 2026年码垛机推荐榜单:全自动/高位/低位/立柱/编织袋/纸箱/桶/粉料/肥料码垛机,江苏/无锡机器人码垛厂家实力解析 - 品牌发掘
  • 机器学习学习路径:从零开始的实战指南
  • 2026 地下水自动化监测仪品牌推荐,生产厂家排行榜 - 王工聊地下水监测
  • 2026年 江苏包装机/全自动包装机/定量包装机,铜精粉吨袋上袋机/包装称/高位码垛机器人,源头实力厂家榜单推荐 - 品牌发掘
  • 机器学习模型上线:从沙盒到生产系统的工程契约

日新闻

  • 2026年不锈钢卷板厂家推荐排行榜:冷轧热轧/304/201不锈钢卷板,高颜值耐腐蚀源头厂家实力精选 - 企业推荐官【官方】
  • FLUX.1-dev FP8模型实战指南:24GB以下显卡高效部署方案
  • 2026佛山长途搬家价目表:跨省跨市搬家费用完整计算指南 - 从来都是英雄出少年

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号