当前位置: 首页 > news >正文

树上背包学习笔记

树上背包学习笔记

做完洛谷P2014实在心绪澎湃,感觉对树上背包有点感触所以分享一下心得

以洛谷P2014为例

我们设状态dp[u][j][m]为以u为根节点,只从前j个子树中选m个点的最大学分

那么这个问题就和01背包很像了,不过对于每个子树(每个物品)还要枚举它可能的不同学分(价值

即在这个子树中选几个点

这么说更像是一个子树代表好几个物品

所以总的来说就是一个01背包了

那么就可以注意到滚动数组优化

第二维可以省略掉

状态转移方程:dp[u][j] = max(dp[u][j], dp[to[i]][k - 1] + v[i] + dp[u][j - k]);(k <- 1 to j)

j倒序枚举,k无所谓(物品出现先后顺序对问题无影响)

代码如下

#include <bits/stdc++.h>
using namespace std;
const int N = 310;
int h[N], to[N], v[N], ne[N], idx;
void add(int a, int b, int c) {to[++idx] = b;ne[idx] = h[a];h[a] = idx;v[idx] = c;
}
int dp[N][N];
void dfs(int u, int m) {if(m == 0) return;for(int i = h[u];i;i = ne[i]) {dfs(to[i], m - 1);for(int j = m;j;--j) {for(int k = j;k;--k) {dp[u][j] = max(dp[u][j], dp[to[i]][k - 1] + v[i] + dp[u][j - k]);}}}
}
int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int n, m;cin>>n>>m;for(int i = 1;i <= n;++i) {int a, b;cin>>a>>b;add(a, i, b);}dfs(0, m);cout<<dp[0][m];return 0;
}
http://www.aitangshan.cn/news/922.html

相关文章:

  • 「HDU6566-The Hanged Man」题解
  • 从Tushare到Wind,散户的Python量化系统搭建实录
  • 内存溢出、内存泄露、内存逃逸三者的区别
  • CentOs8中vi以及vim编辑中文乱码问题
  • ceph日常维护
  • svn
  • Linux 中 同时提取文件的前几行和最后几行
  • CancellationTokenSource 与 CancellationTokenSourceToken
  • 弧焊机器人气体节能指南
  • MSE ZooKeeper:Flink 高可用架构的企业级选择
  • frp内网穿透详解
  • Vue 中如何重置data?
  • linux常用命令工具及问题解决方法系列2
  • 基于线段树的数据结构 - β
  • 华为_DHCP
  • Redis Stream:实时数据流的处理与存储
  • ceph部署
  • 学习记录:23ai新特性:Priority Transactions
  • iOS代码混淆工具怎么选 适合小团队的实用指南
  • 2025 08 12
  • Nginx配置:负载均衡
  • 读书笔记:白话Oracle重做与撤销:数据库的后悔药和时光机
  • Java面向对象
  • 智能台灯离线语音控制芯片方案与应用场景
  • Luogu P3287 [SCOI2014] 方伯伯的玉米田 题解 [ 紫 ] [ 多维 DP ] [ 贪心 ] [ 树状数组 ] [ 状态设计优化 ]
  • VSCode添加到右键菜单中
  • css 红包打开静态效果
  • 厂商官网
  • Java基础学习的一些小细节
  • 2025.8.12 java课堂笔记