AcWing算法提高课 有依赖的背包问题

有依赖的背包问题,节点有树形结构的依赖。

可以递归计算。

递归的过程中,首先对节点的每个子树,计算在不同体积下的最大价值,即dp[u][i]。

dp[u][i]代表在节点u的子树中,选择不超过体积i的物品所得到的最大价值。

然后对当前节点,将每个子节点的每个体积看做分组背包问题中的物品求解。

 

在递归过程中,首先对全部子树DFS(),

然后,首先考虑当前节点,由于当前节点必选,则将小于物品体积的dp[u][i]赋值为负无穷,其余为w[u]。

然后遍历所有子树,遍历当前节点所有体积,遍历子树节点的体积,进行dp。

 

注意分组背包问题如果优化空间,则必须外层遍历体积,内层遍历当前组中的物品,保证小于当前体积的dp没有被更新 

 

10.有依赖的背包问题

代码如下

复制代码
#include<bits/stdc++.h>
using namespace std;

int v[110];
int w[110];
int p[110];
int V;
vector<vector<int>> child(110);
int dp[110][110];
void DFS(int index)
{
    for (auto ch : child[index]) DFS(ch);
    memset(dp[index],-0x3f,sizeof(dp[index]));
    //dp[index][0]=0;
    for (int j = V; j >= v[index]; j--)
    {
        dp[index][j] = w[index];
    }

    for (auto ch : child[index])
    {
        for (int j = V; j >= 0; j--)
        {
            for (int k = j; k >=0; k--)
            {
                dp[index][j] = max(dp[index][j], dp[index][j -k] + dp[ch][k]);
            }
        }
    }
    dp[index][0]=0;
}
int main()
{
    int n;
    cin >> n >> V;
    int root;
    for (int i = 1; i <= n; i++)
    {
        cin >> v[i] >> w[i] >> p[i];
        if (p[i] == -1) root = i;
        else child[p[i]].push_back(i);
    }
    DFS(root);
    //cout << dp[2][8] << endl;
    cout << dp[root][V] << endl;
}
View Code
复制代码

 

posted @   80k  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示