有依赖的背包问题

题目:https://www.acwing.com/problem/content/description/10/

分析

状态表示:f[cur][V]表示当前结点和子树按规则选取的物品可令体积为 (V) 的背包取到的最大价值。

因为在选取物品的时候并不会记录所选取物品的体积,故考虑直接枚举体积实现转移。

状态转移方程: (f[cur][j]=max(f[cur][j],f[son][k]+f[cur][j-k]))

k枚举的是儿子结点的体积,j枚举的是当前结点的体积。

代码:

#include<bits/stdc++.h>
using namespace std;

const int N=105;
int f[N][N];
int v[N],w[N];

int head[N],tot;
struct node{int to,next;}e[N];
void add(int u,int v){e[tot].to=v;e[tot].next=head[u];head[u]=tot++;}
int n,t;

void dfs(int cur){
    for(int i=v[cur];i<=t;i++) f[cur][i]=w[cur];
    for(int i=head[cur];~i;i=e[i].next){
        int son=e[i].to;
        dfs(son);
        for(int j=t;j>=v[cur];j--)
            for(int k=0;k<=j-v[cur];k++)
                f[cur][j]=max(f[cur][j],f[cur][j-k]+f[son][k]);
    }
}
int main(){
    memset(head,-1,sizeof head);
    cin>>n>>t;
    
    int root;
    for(int i=1;i<=n;i++){
        cin>>v[i]>>w[i];
        int fa; cin>>fa;
        if(~fa) add(fa,i);
        else root=i;
    }
    
    dfs(root);
    cout<<f[root][t];
    return 0;
}
原文地址:https://www.cnblogs.com/Tenshi/p/14397352.html