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;
}