有依赖的背包问题
10. 有依赖的背包问题 - AcWing题库
考虑树形 DP
。
假设我们对于
有一种方式是指数级枚举子节点的所有选择方案,但是肯定不可行。
回忆一般背包的状态表示,我们可以直接搬过来用:令
由于以 DP
,然后最后增加回来即可。
对于每棵子树相互独立,且每棵子树只能选择
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define Ed for(int i=h[x];~i;i=ne[i])
#define Ls(i,l,r) for(int i=l;i<r;++i)
#define Rs(i,l,r) for(int i=l;i>r;--i)
#define Le(i,l,r) for(int i=l;i<=r;++i)
#define Re(i,l,r) for(int i=l;i>=r;--i)
#define L(i,l) for(int i=0;i<l;++i)
#define E(i,l) for(int i=1;i<=l;++i)
#define W(t) while(t--)
#define Wh while
const int N=310,M=N;
int n,m;
int h[N],e[M],ne[M],idx,v[N],w[N],f[N][N],tmp[N];//don't forget memset h!
void add(int a,int b){
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int x,int fa){
int mm=m-v[x],val=w[x];
Ed{
int v=e[i];
if(v==fa)continue;
dfs(v,x);
Re(j, mm, 0)
E(k, j)f[x][j]=max(f[x][j],f[x][j-k]+f[v][k]);
}
Re(j, m, v[x])f[x][j]=f[x][j-v[x]]+val;
L(j, v[x])f[x][j]=0;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
#endif
scanf("%d%d",&n,&m);
memset(h,-1,n*4+4);
int rt;
E(i, n){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
~c?add(c,i),0:rt=i;
v[i]=a,w[i]=b;
}
dfs(rt,-1);
printf("%d",f[rt][m]);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现