树上背包学习笔记
0.前言
有一说一,不如先学习泛化物品背包,再学树上背包不是有手就行......吗?
没错,你被骗了,这其实是一篇泛化物品背包学习笔记。但是学习这个之后再去理解树上背包以及推广会轻而易举。
没错,如你所见,这个人一开始用泛化物品概念理解树上背包,但理解透了之后发现自己是个naiver,于是接受了治疗,现已直接能理解树上背包。
1.正文
对于一般的树上背包
设\(f_{i,j}\)表示以\(i\)为根的子树花费\(j\)的代价所能获得的最大价值
理论上这个方程应该长这样,然而这个方程极其恶心,基本上没人想用。
这时我们可以将子树看成一个个物品,那么就转化为了背包问题。
其实这还是到了泛化物品背包的范畴,然而我懒得再改回去了,关于这个我会另写一篇文章的
看一看\(01\)背包的动规方程
我们发现只需要在原来的基础上再加一维,即当前子树的根节点,就可以类似\(01\)背包来解决问题了。
设\(f_{i,j,k}\)表示以\(i\)为根的子树在前\(j\)个子节点花费\(k\)的代价所能获得的最大价值
这样看就干净多了,很明显可以用滚动数组优化。
事实上,树上背包还有另外一种表现形式
这里的并运算指的是将两部分贡献合并,不是集合的并运算。两种方法类似于填表法与刷表法的区别,根据需要选择。
这题是个裸的树上背包,只需要建一个\(0\)虚根就能解决
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
const int MAXN=300+3;
int n,m,val[MAXN],f[MAXN][MAXN];
int size[MAXN];
vector<int> tree[MAXN];
void dfs(int num,int fa){
size[num]=1;
f[num][1]=val[num];
for(auto i:tree[num]){
if(i==fa) continue;
dfs(i,num);
size[num]+=size[i];
for(int j=min(size[num],m+1);j>=1;j--){
for(int k=0;k<j;k++){
f[num][j]=max(f[num][j],f[num][j-k]+f[i][k]);
}
}
}
}
int main(){
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++){
int k,s;
cin>>k>>s;
tree[k].push_back(i);
val[i]=s;
}
dfs(0,-1);
cout<<f[0][m+1]<<endl;
return 0;
}
例题2:P2015 二叉苹果树
同样是一道裸题
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
const int MAXN=1e2+3;
int n,q,ans;
struct Node{
int v,val;
Node(int a,int b){v=a,val=b;}
};
vector<Node> tree[MAXN];
int f[MAXN][MAXN];
int size[MAXN];
void dfs(int num,int fa){
for(auto i:tree[num]){
if(i.v==fa) continue;
dfs(i.v,num);
size[num]+=size[i.v]+1;
for(int j=min(q,size[num]);j>=0;j--){
for(int k=min(j-1,size[i.v]);k>=0;k--){
f[num][j]=max(f[num][j],f[num][j-k-1]+f[i.v][k]+i.val);
}
}
}
}
int main(){
ios::sync_with_stdio(false);
cin>>n>>q;
for(int i=1;i<n;i++){
int u,v,w;
cin>>u>>v>>w;
tree[u].push_back(Node(v,w));
tree[v].push_back(Node(u,w));
}
dfs(1,0);
cout<<f[1][q]<<endl;
return 0;
}
不如做做下面几道
CF161D Distance in Tree(比较水,不过要多维护一个东西)
CF877E Danil and a Part-time Job(不是那么水,但只要发现一个性质就相当简单)
P4516 [JSOI2018] 潜入行动
(配的上评分的题,需要大力分类讨论,还有一些坑)
本文来自博客园,作者:cmd_pig,转载请注明原文链接:https://www.cnblogs.com/cmd-pig/p/16863909.html

浙公网安备 33010602011771号