树形背包

树形背包:必须选择父亲节点才能选择其子节点,求一定体积下的最大点权和
模板题:P2014 [CTSC1997]选课

O ( n w 2 ) O(nw^2) O(nw2) 算法:
d p [ i ] [ j ] dp[i][j] dp[i][j] 表示以 i i i 为根的子树,体积为 j j j 的最大值
d f s dfs dfs 里枚举所有子树的状态即可

注意:若每个点的体积都为 1 1 1 ,选择枚举所有子树的大小,复杂度为 O ( n w ) O(nw) O(nw)

#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
typedef pair <int,int> pii;
const int maxn = 305;
int n, m, k[maxn], s[maxn];
int dp[maxn][maxn];
vector <int> g[maxn];

void dfs(int u){
	dp[u][1] = s[u];
	for(auto v : g[u]){
		dfs(v);
		for(int j=m+1; j; j--)
			for(int k=0; k<j; k++)
				dp[u][j] = max(dp[u][j], dp[u][j-k] + dp[v][k]);
	}
}

signed main() {
	scanf("%d%d", &n, &m);
	for(int i=1; i<=n; i++) {
		scanf("%d%d", k+i, s+i);
		g[k[i]].push_back(i);
	}
	dfs(0);
	printf("%d\n", dp[0][m+1]);	
}

O ( n w ) O(nw) O(nw) 算法:
d p [ i ] [ j ] dp[i][j] dp[i][j] 表示 d f s dfs dfs序下为编号 i i i 的结点,体积为 j j j 的最大值
若选当前节点,直接更新即可
若不选当前节点,则更新下一颗子树
则预处理 d f s dfs dfs 序 与 每个节点的下一颗子树的 d f s dfs dfs 序号

#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
typedef pair <int,int> pii;
const int maxn = 305;
int n, m, k[maxn], s[maxn];
int dp[maxn][maxn], v[maxn];
int dfn[maxn], tot, nxt[maxn];
vector <int> g[maxn];

void dfs(int u){
	dfn[u] = tot++;
	for(auto v : g[u]) dfs(v);
	nxt[dfn[u]] = tot;
}

signed main() {
	scanf("%d%d", &n, &m); m++;
	for(int i=1; i<=n; i++) {
		scanf("%d%d", k+i, s+i);
		g[k[i]].push_back(i);
	}
	dfs(0);
	memset(dp, 128, sizeof(dp));
	memset(dp[0], 0, sizeof(dp[0]));
	for(int i=1; i<=n; i++) v[dfn[i]] = s[i];
	for(int i=0; i<=n; i++)
		for(int j=0; j<=min(i, m); j++){
			dp[i+1][j+1] = max(dp[i+1][j+1], dp[i][j] + v[i]);
			dp[nxt[i]][j] = max(dp[nxt[i]][j], dp[i][j]);
		}
	printf("%d\n", dp[n+1][m]);	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值