[There are] problem solution AcWing10 dependent knapsack problem

Face questions

Classic problem tree DP.

We set \ (dp_ {i, j} \) indicates that the current node is \ (I \) , the subtree of the current node (including the current node) the volume is filled up \ (J \) is the maximum value.

As we traverse the node is equivalent to a packet backpack done it again.

Note After complete traverse all the child nodes to be updated about the status.

#include <bits/stdc++.h>

using namespace std;

const int maxn = 103;

int n, m;
int tot, head[maxn], ver[maxn * 2], nxt[maxn * 2];
int dp[maxn][maxn];
int v[maxn], w[maxn], p[maxn];

inline void add(int u, int v)
{
    ver[++tot] = v, nxt[tot] = head[u], head[u] = tot;
}

void dfs(int u, int f)
{
    for (int i = head[u]; i; i = nxt[i]) //循环组数
    {
        int vv = ver[i];
        if (vv == f) continue;
        dfs(vv, u); //遍历子节点
        for (int j = m - v[u]; j >= 0; j-=1) //循环体积
            for (int k = 0; k <= j; k+=1) //循环决策
                dp[u][j] = max(dp[u][j], dp[u][j - k] + dp[vv][k]); //状态转移
    }
    //更新状态
    for (int i = m; i >= v[u]; i-=1) dp[u][i] = dp[u][i - v[u]] + w[u]; 
    for (int i = 0; i < v[u]; i+=1) dp[u][i] = 0; 
}

int main()
{
    cin >> n >> m;
    int rt = -1; //根节点
    for (int i = 1; i <= n; i+=1) 
    {
        cin >> v[i] >> w[i] >> p[i];
        if (p[i] == -1) rt = i;
        else add(i, p[i]), add(p[i], i); //建树
    }
    dfs(rt, 0);
    cout << dp[rt][m] << endl;
    return 0;
}

Guess you like

Origin www.cnblogs.com/xsl19/p/12337084.html