zoukankan      html  css  js  c++  java
  • 【树形DP】【分组背包】【HDU1561】

    【题目来源】http://acm.hdu.edu.cn/showproblem.php?pid=1561

    【题目解析】有树形依赖的背包问题。

          流传较广的是多叉树转二叉树的DP方法。首先运用“左儿子右兄弟”的方法将多叉树转化为二叉树。这样的话,DP的进程就更加容易。由于是二叉,那么只需要枚举分配给左儿子多少个点,分配给右儿子(右兄弟)多少个点即可。不过需要注意的是枚举给左儿子的时候记得给父亲留一个点,因为是依赖的;枚举给右儿子的时候可以全部给它,因为它和父节点是兄弟关系。

          这里要解析的是直接多叉树DP,即直接在原有的树上面进行DP。从递归的角度来考虑:把根节点看成是一个容量为V背包,其所有的子树看成是物品。枚举每个子树,对于某个子树来说,先去掉这棵子树根节点的体积W,递归求出剩下的V-W容量的背包能装下这个子树的子树的物品。那么将会得到一个从0..V-W的一个01背包,把每一个体积及其对应的价值看成是一个物品,因此共有V-W+1个物品,每个物品再算上所去掉的根节点。那么新的这V-W+1个物品可以看成是一个分组,物品之间是互斥的,只能选择其一。由此可见,对于每个根节点来说,它的所有子树就可以看成是一组组的分组物品,各组内部的物品之间是互斥的,只能选择其一。所以问题最终的本质是在树上进行的分组背包。

    【代码如下】

     1 #include <iostream>
     2 #include <cstring>
     3 
     4 using namespace std;
     5 
     6 const int Max = 201;
     7 
     8 struct edge
     9 {
    10     int v;
    11     edge* next;
    12     edge(int _v, edge* _next) : v(_v), next(_next) {}
    13 }* E[Max];
    14 
    15 int N, V, F[Max][Max], C[Max];
    16 
    17 void Clear()
    18 {
    19     memset(F, 0, sizeof(F));
    20     memset(E, 0, sizeof(E));
    21 }
    22 
    23 void Dp(int i, int V)
    24 {
    25     for (edge* j = E[i]; j; j = j -> next)
    26     {
    27         int v = j -> v;
    28         Dp(v, V - 1);
    29         for (int k = V; k >= 0; k --)
    30             for (int l = 0; l < min(V, k); l ++)
    31                 F[i][k] = max(F[i][k], F[i][k - (l + 1)] + F[v][l] + C[v]);
    32     }
    33 }
    34 
    35 inline void edgeAdd(int x, int y)
    36 {
    37     E[x] = new edge(y, E[x]);
    38 }
    39 
    40 void Init()
    41 {
    42     for (int i = 1, x; i <= N; i ++)
    43     {
    44         cin >> x >> C[i];
    45         edgeAdd(x, i);
    46     }
    47 }
    48 
    49 int main()
    50 {
    51     cin >> N >> V;
    52     while (N || V)
    53     {
    54         Init();
    55         Dp(0, V);
    56         cout << F[0][V] << endl;
    57         Clear();
    58         cin >> N >> V;
    59     }
    60     return 0;
    61 }
  • 相关阅读:
    PointToPointNetDevice doesn't support TapBridgeHelper
    NS3系列—10———NS3 NodeContainer
    NS3系列—9———NS3 IP首部校验和
    NS3系列—8———NS3编译运行
    【习题 7-6 UVA
    【Good Bye 2017 C】 New Year and Curling
    【Good Bye 2017 B】 New Year and Buggy Bot
    【Good Bye 2017 A】New Year and Counting Cards
    【Educational Codeforces Round 35 D】Inversion Counting
    【Educational Codeforces Round 35 C】Two Cakes
  • 原文地址:https://www.cnblogs.com/GXZC/p/2851761.html
Copyright © 2011-2022 走看看