树形背包问题

一些题目给定了树形结构,在这个树形结构中选取一定数量的点或边(也可能是其他属性),使得某种与点权或者边权相关的花费最大或者最小。解决这类问题,一般要考虑使用树上背包。

树上背包,顾名思义,就是在树上做背包问题。一个节点的若干子树可以看作是若干组背包,也就是用树形dp的方式做分组背包问题。一般来说,f ( i , j ) f(i,j)f(i,j)表示以i ii为根的子树中,在j jj的容量范围内,最大或者最小可以获得多少收益。根据分组背包的思想,第一维枚举物品(在树上指的是子树),第二维枚举容量,第三维枚举决策(这里指的是给子树分配多少容量)。基本的代码框架如下:

void dfs(int u, int fa)
{
	for(int i = h[u]; ~i; i = ne[i])
	{
		int son = e[i];
		if(son == fa) continue;
		dfs(son, u);
		for(int j = m; j >= 0; j --)
			for(int k = 0; k <= j; k ++)
				f[u][j] = max(f[u][j], f[u][j-k] + f[son][k] + val);
	}
}

有依赖的背包

在这里插入图片描述

void dfs(int u, int fa)
{
	for(int i = h[u]; ~i; i = ne[i])
	{
		int son = e[i];
		if(son == fa) continue;
		dfs(son, u);
		for(int j = m; j >= 0; j --)
			for(int k = 0; k <= j; k ++)
				f[u][j] = max(f[u][j], f[u][j-k] + f[son][k] + val);
	}
}

二叉苹果树

在这里插入图片描述

在这里插入图片描述

void dfs(int u, int fa)
{
    for(int i = h[u]; ~i; i = ne[i])
    {
    	int son = e[i];
        if(son == fa) continue;
        dfs(son, u);
        for(int j = m; j >= 1; j -- )
            for(int k = 0; k <= j - 1; k ++ )
                f[u][j] = max(f[u][j], f[u][j - k - 1] + f[son][k] + w[i]);
    }
}

相关推荐

  1. 多重背包问题 Ⅰ&Ⅱ &Ⅲ

    2024-07-20 17:32:03       47 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-20 17:32:03       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-20 17:32:03       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-20 17:32:03       45 阅读
  4. Python语言-面向对象

    2024-07-20 17:32:03       55 阅读

热门阅读

  1. 二分 以及例题

    2024-07-20 17:32:03       22 阅读
  2. MySQL——视图

    2024-07-20 17:32:03       20 阅读
  3. Window任务栏应用图片无法加载解决方法

    2024-07-20 17:32:03       17 阅读
  4. linux shell(上)

    2024-07-20 17:32:03       21 阅读
  5. RK3588 编译opencv&opencv_contrib记录

    2024-07-20 17:32:03       25 阅读
  6. 二叉树---路径总和

    2024-07-20 17:32:03       18 阅读