2020ICPC 南京 Monster Hunter(树形依赖背包)

2024-04-15 23:18

本文主要是介绍2020ICPC 南京 Monster Hunter(树形依赖背包),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

好久没写树形DP手生疏了。

题意:
每个点权值为 h p [ x ] + h p [ v ] hp[x]+hp[v] hp[x]+hp[v],其中 v v v x x x的儿子。你可以删掉 m m m个点,求对于 0 ≤ m ≤ n 0≤m≤n 0mn的每个 m m m能得到的最小权值和。

思路:
定义 d p [ i ] [ j ] [ 0 / 1 ] dp[i][j][0/1] dp[i][j][0/1]代表点 i i i为根子树,删掉了 j j j个点, i i i是否被删能得到的最小权值和。
转移就是按照基本的背包转移,不再赘述。

但是注意一点,转移过程中其实隐含了 d p [ i ] [ j ] [ 0 / 1 ] dp[i][j][0/1] dp[i][j][0/1]是前 x x x个子树得到的结果,所以这里其实有滚动的过程,要开个临时数组。以前写这种类型题的时候由于是求最大权值和,所以可以直接转移过去,不需要滚动或者开临时数组。但是这里是取最小值,很必要,结果赛中写的时候输出的结果一直是INF ┭┮﹏┭┮。

ps:还有这个转移居然是 n 2 n^2 n2的,我还想着按照子树大小排个序看看能否水一水或者dfs序优化(想写,但是不知道怎么初始化状态),结果这居然是正解XD。不过冷静分析一下还是可以发现,转移实际就是枚举任意两点LCA,所以复杂度 n 2 n^2 n2

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>using namespace std;
const int maxn = 2e3 + 7;
typedef long long ll;
const ll INF = 1e18;
vector<int>G[maxn];
ll dp[maxn][maxn][2],tmp[maxn][2];
ll hp[maxn];
int siz[maxn];void dfs(int x) {siz[x] = 1;for(int t = 0;t < G[x].size();t++) {int v = G[x][t];dfs(v);for(int i = 0;i <= siz[x] + siz[v];i++) {tmp[i][0] = tmp[i][1] = INF;}for(int i = 0;i <= siz[x];i++) {for(int j = 0;j <= siz[v];j++) {tmp[i + j][0] = min(tmp[i + j][0],dp[x][i][0] + dp[v][j][0] + hp[v]);if(j > 0) {tmp[i + j][0] = min(tmp[i + j][0],dp[x][i][0] + dp[v][j][1]);}if(i > 0) {tmp[i + j][1] = min(tmp[i + j][1],dp[x][i][1] + dp[v][j][0]);}if(i > 0 && j > 0) {tmp[i + j][1] = min(tmp[i + j][1],dp[x][i][1] + dp[v][j][1]);}}}for(int j = 0;j <= siz[x] + siz[v];j++) {dp[x][j][0] = tmp[j][0];dp[x][j][1] = tmp[j][1];}siz[x] += siz[v];}for(int i = 0;i <= siz[x];i++) {dp[x][i][0] += hp[x];}
}int main() {int T;scanf("%d",&T);while(T--) {int n;scanf("%d",&n);for(int i = 1;i <= n;i++) {for(int j = 0;j <= n;j++) {dp[i][j][0] = dp[i][j][1] = 0;}}for(int i = 1;i <= n;i++) G[i].clear();for(int i = 2;i <= n;i++) {int f;scanf("%d",&f);G[f].push_back(i);}for(int i = 1;i <= n;i++) {scanf("%lld",&hp[i]);}dfs(1);for(int i = 0;i <= n;i++) {printf("%lld ",min(dp[1][i][0],dp[1][i][1]));}printf("\n");}return 0;
}

这篇关于2020ICPC 南京 Monster Hunter(树形依赖背包)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/907209

相关文章

javacv依赖太大导致jar包也大的解决办法

《javacv依赖太大导致jar包也大的解决办法》随着项目的复杂度和依赖关系的增加,打包后的JAR包可能会变得很大,:本文主要介绍javacv依赖太大导致jar包也大的解决办法,文中通过代码介绍的... 目录前言1.检查依赖2.更改依赖3.检查副依赖总结 前言最近在写项目时,用到了Javacv里的获取视频

Spring 依赖注入与循环依赖总结

《Spring依赖注入与循环依赖总结》这篇文章给大家介绍Spring依赖注入与循环依赖总结篇,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. Spring 三级缓存解决循环依赖1. 创建UserService原始对象2. 将原始对象包装成工

Spring-DI依赖注入全过程

《Spring-DI依赖注入全过程》SpringDI是核心特性,通过容器管理依赖注入,降低耦合度,实现方式包括组件扫描、构造器/设值/字段注入、自动装配及作用域配置,支持灵活的依赖管理与生命周期控制,... 目录1. 什么是Spring DI?2.Spring如何做的DI3.总结1. 什么是Spring D

Springboot项目构建时各种依赖详细介绍与依赖关系说明详解

《Springboot项目构建时各种依赖详细介绍与依赖关系说明详解》SpringBoot通过spring-boot-dependencies统一依赖版本管理,spring-boot-starter-w... 目录一、spring-boot-dependencies1.简介2. 内容概览3.核心内容结构4.

SpringBoot利用树形结构优化查询速度

《SpringBoot利用树形结构优化查询速度》这篇文章主要为大家详细介绍了SpringBoot利用树形结构优化查询速度,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一个真实的性能灾难传统方案为什么这么慢N+1查询灾难性能测试数据对比核心解决方案:一次查询 + O(n)算法解决

Java Spring的依赖注入理解及@Autowired用法示例详解

《JavaSpring的依赖注入理解及@Autowired用法示例详解》文章介绍了Spring依赖注入(DI)的概念、三种实现方式(构造器、Setter、字段注入),区分了@Autowired(注入... 目录一、什么是依赖注入(DI)?1. 定义2. 举个例子二、依赖注入的几种方式1. 构造器注入(Con

解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题

《解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题》:本文主要介绍解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4... 目录未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘打开pom.XM

IDEA Maven提示:未解析的依赖项的问题及解决

《IDEAMaven提示:未解析的依赖项的问题及解决》:本文主要介绍IDEAMaven提示:未解析的依赖项的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录IDEA Maven提示:未解析的依编程赖项例如总结IDEA Maven提示:未解析的依赖项例如

Python pip下载包及所有依赖到指定文件夹的步骤说明

《Pythonpip下载包及所有依赖到指定文件夹的步骤说明》为了方便开发和部署,我们常常需要将Python项目所依赖的第三方包导出到本地文件夹中,:本文主要介绍Pythonpip下载包及所有依... 目录步骤说明命令格式示例参数说明离线安装方法注意事项总结要使用pip下载包及其所有依赖到指定文件夹,请按照以

Java -jar命令如何运行外部依赖JAR包

《Java-jar命令如何运行外部依赖JAR包》在Java应用部署中,java-jar命令是启动可执行JAR包的标准方式,但当应用需要依赖外部JAR文件时,直接使用java-jar会面临类加载困... 目录引言:外部依赖JAR的必要性一、问题本质:类加载机制的限制1. Java -jar的默认行为2. 类加