依赖背包

487. 金明的预算方案
思路: 一个商品只能依赖或者被依赖且依赖个数比较小,直接将同一依赖下的物品分组。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#define v first 
#define w second 
using namespace std;
typedef pair<int,int> PII;
typedef long long LL;
const int N=32010,M=70,V=10010;
PII master[M];
vector<PII> attach[M];
LL f[N];
int main(){
    int n,m;
    cin>>m>>n;
    for(int i=1;i<=n;++i){
        int v,w,q;
        cin>>v>>w>>q;
        if(!q){
            master[i]={v,w};
        }
        else {
            attach[q].push_back({v,w});
        }
    }
    for(int i=1;i<=n;++i){
        if(master[i].w){
            for(int j=m;j>=0;--j){
                for(int k=0;k<(1<<attach[i].size()) ;++k){
                    LL vv=master[i].v,ww=master[i].w*master[i].v;
                    for(int l=0;l<(int)attach[i].size(); ++l){
                        if(k&(1<<l)) vv+=attach[i][l].v,ww+=attach[i][l].v*attach[i][l].w;
                    }
                    if(j>=vv)
                        f[j]=max(f[j],f[j-vv]+1LL*ww);
                }
            }
        }
    }
    cout<<f[m]<<endl;
    return 0;
}

10. 有依赖的背包问题

思路: 树形dp+分组背包

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=110;
int f[N][N],v[N],w[N],p[N],head[N],n,m,tot;
struct eg{
    int v,nex;
}edge[N];
void dfs(int u){
    for(int j=m;j>=v[u];--j){
        f[u][j]=w[u];
    }
    for(int i=head[u];~i;i=edge[i].nex){
        int son=edge[i].v;
        dfs(son);
        for(int j=m;j>=v[u];--j){
            for(int k=1;j-k>=v[u];++k){
                f[u][j]=max(f[u][j-k]+f[son][k],f[u][j]);
            }
        }
    }
}
int main(){
    cin>>n>>m;
    int root;
    memset(head,-1,sizeof head);
    for(int i=1;i<=n;++i){
        cin>>v[i]>>w[i]>>p[i];
        if(p[i]==-1) root=i;
        else {
            edge[++tot]=(eg){i,head[p[i]]};
            head[p[i]]=tot;
        }
    }
    dfs(root);
    cout<<f[root][m]<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/jjl0229/p/12571233.html