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

dp进阶,树形背包(dfs+01)

顾名思义,就是在对树进行搜索的时候,由于限制了子节点选根节点必选和节点数限制,所以需要额外利用背包来维护最大值

假设根节点就是0,我们很容易 发现,这就是一个正常的树求和,但是限制了节点数量,所以需要用背包去规划这个限制(容量)

局部分析:取一个倒数2小的子节点,可以求出该节点下面选择0-n个子节点的最大值

        dp[x][i]:x代表该节点的序号,i代表这个节点占多大容量,dp[x][i]自然就是维护的最大值;将其上传,一直到【0】【m】的最大值

#include <bits/stdc++.h>
using namespace std;
int n,m;
struct ed{
    int next,to;
}e[1000];//ed结构体用于存储边信息,采用邻接表存储树结构。当然也可以用vector<vector<int>>

  • to:表示当前边的终点节点编号。在树的结构中,它指的是子节点的编号。
  • next:指向下一条从同一节点出发的边的索引。在邻接表中,它用于将同一个起点的所有边连接成一个链表。

int rt,h[1000],o,v[1000],dp[1000][1000];//h[1000]是邻接表的头数组,o是边计数器。v[1000]存储每个节点的权值。dp[u][t]表示以节点u为根的子树中选择t个节点能获得的最大权值。

void add(int x,int y){//邻接表添加边:将节点y添加为节点x的子节点。(用vector<vector<int>>就                                                       // 不用写这个惹。但是处理的效率会下降)

    e[++o].next=h[x];
    h[x]=o;
    e[o].to=y;
}

邻接表的工作原理

  1. 每个节点通过一个头指针(h 数组)指向第一条边
  2. 每条边e 数组中的元素)包含两个信息:
    • to:表示这条边指向的节点
    • next:指向下一条边的索引,形成链表


void dfs(int u,int t){
    if (t<=0) return ;
    for (int i=h[u]; i; i=e[i].next){//遍历
        int p = e[i].to;//到子节点i
        for (int k=0; k<t; ++k) 
            dp[p][k] = dp[u][k]+v[p];//在父节点 u 已经选择了 k 个节点的基础上,选择子节点 p(并获得其权值 v[p]
        dfs(p,t-1);
        for (int k=1; k<=t; ++k) 
            dp[u][k] = max(dp[u][k],dp[p][k-1]);
    }
}

动态规划核心函数:

  1. 终止条件:如果剩余选择次数t小于等于 0,直接返回。
  2. 初始化子节点 DP 值:对于每个子节点p,初始化dp[p][k]dp[u][k] + v[p],表示在父节点已选状态下选择子节点。
  3. 递归处理子树:递归调用dfs(p, t-1)处理子树,限制子树最多选择t-1个节点。
  4. 更新父节点 DP 值:通过子节点的 DP 值更新父节点的 DP 值,取最大值。


int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        int a;
        scanf("%d%d",&a,&v[i]);
        if(a)
          add(a,i);
        if(!a)add(0,i);
    }
    dfs(0,m);
    printf("%d",dp[0][m]);
}

http://www.lryc.cn/news/575995.html

相关文章:

  • 自动对焦技术助力TGV检测 半导体检测精度大突破
  • 本地部署 WordPress 博客完整指南(基于 XAMPP)
  • Bootstrap 5学习教程,从入门到精通,Bootstrap 5 侧边栏导航(Offcanvas) 语法知识点及案例(26)
  • oracle基础审计管理
  • Django实战:自定义中间件实现全链路操作日志记录
  • IPv6配置
  • MySQL主从备份
  • 16.2 Docker多阶段构建实战:LanguageMentor镜像瘦身40%,支持500+并发1.2秒响应!
  • 2025年智能营销产品发展和应用趋势
  • uniapp消息推送
  • 向量关于基的坐标向量
  • 图像分割模型中的空间信息、上下文信息、空间路径、上下文路径到底是什么?有什么作用?
  • 【C++】atoi和std::stoi
  • redisTemplate简单实现幂等性校验
  • 微信小程序进度条progress支持渐变色
  • 【vue3】打包配置webpack压缩,哈希值设置
  • CVE-2015-5531源码分析与漏洞复现(Elasticsearch目录遍历漏洞)
  • 高斯混合模型GMMK均值(十三-1)——K均值是高斯混合模型的特例
  • macOS,切换 space 失效,向右切换space(move right a space) 失效
  • [论文阅读] 人工智能 | 真实场景下 RAG 系统的工程实践指南
  • JUC:7线程的五种状态与六种状态
  • AI歌手Yuri出道:GenAI,透露着新的AI产业机遇?
  • 增加寒武纪MLU270视频转码
  • 大数据赋能智能家居:打造你贴心的“数字管家”
  • STM32安全固件升级:使用自定义 bootloader 实现SD卡固件升级,包含固件加密
  • 【stm32】HAL库开发——CubeMX配置串口通讯(中断方式)
  • virtual box 配置ubuntu 22.04网络与SSH服务
  • A模块 系统与网络安全 第三门课 网络通信原理-2
  • 24CJ87-4:圆拱型采光排烟天窗
  • Pytorch基础函数速查