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

相关文章

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

Maven如何手动安装依赖到本地仓库

《Maven如何手动安装依赖到本地仓库》:本文主要介绍Maven如何手动安装依赖到本地仓库问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、下载依赖二、安装 JAR 文件到本地仓库三、验证安装四、在项目中使用该依赖1、注意事项2、额外提示总结一、下载依赖登

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

Python如何自动生成环境依赖包requirements

《Python如何自动生成环境依赖包requirements》:本文主要介绍Python如何自动生成环境依赖包requirements问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录生成当前 python 环境 安装的所有依赖包1、命令2、常见问题只生成当前 项目 的所有依赖包1、

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

使用Java实现通用树形结构构建工具类

《使用Java实现通用树形结构构建工具类》这篇文章主要为大家详细介绍了如何使用Java实现通用树形结构构建工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录完整代码一、设计思想与核心功能二、核心实现原理1. 数据结构准备阶段2. 循环依赖检测算法3. 树形结构构建4. 搜索子

Python依赖库的几种离线安装方法总结

《Python依赖库的几种离线安装方法总结》:本文主要介绍如何在Python中使用pip工具进行依赖库的安装和管理,包括如何导出和导入依赖包列表、如何下载和安装单个或多个库包及其依赖,以及如何指定... 目录前言一、如何copy一个python环境二、如何下载一个包及其依赖并安装三、如何导出requirem

Python如何快速下载依赖

《Python如何快速下载依赖》本文介绍了四种在Python中快速下载依赖的方法,包括使用国内镜像源、开启pip并发下载功能、使用pipreqs批量下载项目依赖以及使用conda管理依赖,通过这些方法... 目录python快速下载依赖1. 使用国内镜像源临时使用镜像源永久配置镜像源2. 使用 pip 的并

python安装whl包并解决依赖关系的实现

《python安装whl包并解决依赖关系的实现》本文主要介绍了python安装whl包并解决依赖关系的实现,文中通过图文示例介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录一、什么是whl文件?二、我们为什么需要使用whl文件来安装python库?三、我们应该去哪儿下

Spring AI Alibaba接入大模型时的依赖问题小结

《SpringAIAlibaba接入大模型时的依赖问题小结》文章介绍了如何在pom.xml文件中配置SpringAIAlibaba依赖,并提供了一个示例pom.xml文件,同时,建议将Maven仓... 目录(一)pom.XML文件:(二)application.yml配置文件(一)pom.xml文件:首