码迷,mamicode.com
首页 > 其他好文 > 详细

有依赖的背包问题(树状dp 深搜)

时间:2020-10-30 12:56:08      阅读:20      评论:0      收藏:0      [点我收藏+]

标签:cout   string   turn   str   范围   选择   main   情况   code   

有 N 个物品和一个容量是 V 的背包。

物品之间具有依赖关系,且依赖关系组成一棵树的形状。如果选择一个物品,则必须选择它的父节点。

如下图所示:
技术图片

如果选择物品5,则必须选择物品1和2。这是因为2是5的父节点,1是2的父节点。

每件物品的编号是 i,体积是 vi,价值是 wi,依赖的父节点编号是 pi。物品的下标范围是 1…N。

求解将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大。

输出最大价值。

输入格式
第一行有两个整数 N,V,用空格隔开,分别表示物品个数和背包容量。

接下来有 N 行数据,每行数据表示一个物品。
第 i 行有三个整数 vi,wi,pi,用空格隔开,分别表示物品的体积、价值和依赖的物品编号。
如果 pi=?1,表示根节点。 数据保证所有物品构成一棵树。

输出格式
输出一个整数,表示最大价值。

数据范围
1≤N,V≤100
1≤vi,wi≤100
父节点编号范围:

内部结点:1≤pi≤N;
根节点 pi=?1;
输入样例
5 7
2 3 -1
2 2 1
3 5 1
4 7 2
3 6 2
输出样例:
11

思路:
题意就是选某一个点 然后这个点的 所有依赖节点都要存放进去 然后 在不超过背包容积的情况下得到值的最大;
分析:顺序遍历 以某一个点作为根节点向下遍历出来 去掉这个根节点的容量(因为每一次我们必须要选择这个点) ,看所有儿子节点选或者不选的情况 然后儿子节点也可能还有儿子节点 就是一个递归处理
每一次去掉根节点后剩下的背包容量分给儿子节点 (这里就是一个分组背包 )看一看如何分配能取到最大值
最后把根节点的价值加上 如果小于根节点的容积 那么就是0 取不了这个物品


#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 110;
int dp[N][N],w[N],v[N];
int n , m;
int idx, h[N],ne[N],e[N];
void add(int a, int b)
{
    e[idx] = b;
    ne[idx] = h[a];
    h[a] = idx++;
}

void dfs(int u)
{
   for(int i = h[u] ; ~i ; i = ne[i])
   {
       
       int son = e[i];
       dfs(e[i]);
       
       //分组背包
       for(int j = m - v[u] ; j >= 0 ; j --)//去掉根节点的容积遍历 如何分配
       {
           for(int k = 0 ; k <= j ; k++)//分给儿子的容积k能大到多少决策 dp[u][j-k] 就是能分配给根节点的容积是多少
           {
               dp[u][j] = max(dp[u][j] , dp[u][j-k] + dp[son][k]);//
           }
       }
       
   }
   
   for(int i = m ; i >= v[u] ; i --) dp[u][i] = dp[u][i-v[u]] + w[u];
   
   for(int i = 0 ; i < v[u];i++) dp[u][i] = 0; 
   
}
int main()
{
    cin >> n >> m ;
    memset(h,-1,sizeof h);
      int root;
    for(int i =1 ; i <= n ; i++)
    {
          int p;
        cin >> v[i] >>w[i] >> p ;
        if(p == -1)root = i;
        else add(p,i);
    }
    
      dfs(root);
    cout << dp[root][m] << endl;
    return 0 ;
}

有依赖的背包问题(树状dp 深搜)

标签:cout   string   turn   str   范围   选择   main   情况   code   

原文地址:https://www.cnblogs.com/wk-love-zsy/p/13899958.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!