P9634 [ICPC2020 Nanjing R] Monster Hunter 题解
考虑树上背包。但是直接设
于是加一维,
转移时朴素地类似树上背包转移即可。
时间复杂度
#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;
}
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现