[总结]树形依赖背包的优化方法
2018-08-19 21:00
302 查看
树形背包依赖问题
每个点有权值和体积,如果要选它就必须选它的父亲,问体积和≤m的情况下的最大点权和。
如果体积为1,直接做是 \(n^2\) 的。
否则是 \(nm^2\) 的。
我们可以求出这棵树的后序遍历,即先访问儿子再访问自己。
那么对于 \(i\) 这个点,它的子树是 \(i\) 之前连续的一段,且 \(i\) 是最后一个点。
枚举 \(i\) 选不选,如果选,那么从 \(f[i-1]\) 转移来,否则从 \(f[i-sze[i]]\;copy\) 来。
复杂度 \(nm\),每个点都只做了一遍背包。
例题:JZOJ5661 药香沁鼻
裸
#include<cstdio> #include<cctype> #include<cstring> #include<iostream> #include<algorithm> #define N 5005 #define M 10005 using std::min; using std::max; using std::swap; int sze ; int f [M]; int head ; int a ,b ; int n,m,tot,cnt; struct Edge{ int to,nxt; }edge[N<<1]; void add(int x,int y){ edge[++cnt].to=y; edge[cnt].nxt=head[x]; head[x]=cnt; } int getint(){ int x=0,f=0;char ch=getchar(); while(!isdigit(ch)) f|=ch=='-',ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return f?-x:x; } void dfs(int now){ sze[now]=1; for(int i=head[now];i;i=edge[i].nxt){ int to=edge[i].to; dfs(to);sze[now]+=sze[to]; } int dfn=++tot; for(int j=0;j<=m;j++){ if(j<a[now]) f[dfn][j]=f[dfn-sze[now]][j]; else f[dfn][j]=max(f[dfn-sze[now]][j],f[dfn-1][j-a[now]]+b[now]); } } signed main(){ n=getint(),m=getint(); for(int i=1;i<=n;i++){ a[i]=getint(); int x=getint(); if(x!=i) add(x,i); b[i]=getint(); } dfs(1); printf("%d\n",f[tot][m]); return 0; }
相关文章推荐
- 树形依赖背包的优化方法
- hdu 3593 树形依赖背包的优化
- 一类有依赖的树形背包dp方法
- 关系数据库的查询优化策略----总结了一些查询优化的方法,希望可以对大家有所帮助
- C++代码优化方法总结
- C++代码优化方法总结
- 总结的ASP.NET 常用性能优化方法
- HBase性能优化方法总结(三):读表操作
- Deep Learning 优化方法总结
- HBase性能优化方法总结
- HBase性能优化方法总结
- Unity+NGUI性能优化方法总结
- Tomcat并发数优化的方法总结
- 深度学习最全优化方法总结比较(SGD,Adagrad,Adadelta,Adam,Adamax,Nadam)
- HDU 1011 Starship Troopers---树形dp+有依赖的背包
- IT第七天 - 类及其属性、方法的理解,断点调试初识,代码优化总结,编程逻辑培养
- CDOJ 1136 邱老师玩游戏 树形01背包 (有依赖的背包问题)
- HBase性能优化方法总结
- Tomcat并发数优化的方法总结
- [HBase] HBase性能优化方法总结