P9634 [ICPC2020 Nanjing R] Monster Hunter 题解

考虑树上背包。但是直接设 fi,jf_{i,j} 表示以 ii 为根的子树中用了 jj 次魔法难以转移,问题在于难以确定 ii 的儿子是否呗魔法标记。

于是加一维,fi,j,0/1f_{i,j,0/1} 表示以 ii 为根的子树中用了 jj 次魔法,ii 点被魔法标记了或没有被标记。00 表示被标记,11 表示没有被标记。

转移时朴素地类似树上背包转移即可。

时间复杂度 O(n2)O(n^2)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
using namespace std;

const int N = 2e3 + 5;

long long f[N][N][2], hp[N], tmp[N][N][2];
// f[i][j][0]: 根不存在,f[i][j][1]:根存在
vector<int> G[N];
int t, n;
int sz[N];

void dfs(int u, int fa)
{
	f[u][1][0] = 0LL;
	f[u][0][1] = hp[u];
	sz[u] = 1;
	int c = 0;
	for (auto& j : G[u])
	{
		if (j == fa) continue;
		c++;
		dfs(j, u);
		for (int i = 0; i <= sz[u] + sz[j]; i++) tmp[u][i][0] = tmp[u][i][1] = (long long)1e18;
		for (int i = 0; i <= sz[j]; i++) // 枚举子树 j 删的个数
		{
			for (int k = 0; k <= sz[u]; k++) // 枚举当前子树删的个数
			{
				int tot = i + k;
				tmp[u][tot][0] = min(tmp[u][tot][0], min(f[j][i][0], f[j][i][1]) + f[u][k][0]);
			}
		}
		for (int i = 0; i <= sz[j]; i++) // 枚举子树 j 删的个数
		{
			for (int k = 0; k <= sz[u]; k++) // 枚举当前子树删的个数
			{
				int tot = i + k;
				tmp[u][tot][1] = min(tmp[u][tot][1], min(f[j][i][0], f[j][i][1] + hp[j]) + f[u][k][1]);
			}
		}
		sz[u] += sz[j];
		for (int i = 0; i <= sz[u]; i++) f[u][i][0] = tmp[u][i][0], f[u][i][1] = tmp[u][i][1];
	}
	if (f[u][sz[u]][0] != 0) cout << "error: " << u << "\n";
}

int main()
{
	ios::sync_with_stdio(0), cin.tie(0);
	cin >> t;
	while (t--)
	{
		cin >> n;
		for (int i = 1; i <= n; i++) G[i].clear(), G[i].shrink_to_fit();
		for (int i = 2; i <= n; i++)
		{
			int fa;
			cin >> fa;
			G[fa].emplace_back(i);
		}
		for (int i = 1; i <= n; i++) cin >> hp[i];
		for (int i = 1; i <= n; i++)
		{
			for (int j = 0; j <= n; j++) f[i][j][0] = f[i][j][1] = (long long)1e18;
		}
		dfs(1, 0);
		for (int i = 0; i <= n; i++) cout << min(f[1][i][0], f[1][i][1]) << " ";
		cout << "\n";
	}
	return 0;
}
posted @   HappyBobb  阅读(7)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示