第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(南京)M Monster Hunter —— 树形DP

本文主要是介绍第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(南京)M Monster Hunter —— 树形DP,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

This way

题意:

现在有一棵根为1的树,你要将所有点消除,消除一个点i首先需要消除它的父亲,然后消除i的代价是
在这里插入图片描述
也就是hp[i]+还未被消除的所有儿子的hp和
你有一种魔法可以无视所有规则消除掉一个点。
问你这个魔法的使用次数为i(0<=i<=n)次时,最少需要的代价是多少。

题解:

很明显是树形DP,但是枚举儿子的状态转移的话,时间复杂度会变成 n 3 n^3 n3,所以需要使用上下界优化
那么消除当前数的时候,需要加上所有未被消除的儿子的值,因此DP需要三维
dp[i][j][k]表示到了第i个点,使用了j次魔法,当前点是否一开始就使用魔法消除时最小的代价。
那么边界值:
dp[x][1][0]=0
dp[x][0][1]=a[x]
然后转移:
首先是这个点在一开始就被消除
dp[x][i+j][0]=min(dp[x][i+j][0],dp[x][i][0]+min(dp[ne][j][0],dp[ne][j][1]));
还有一种就是这个点按照常规的消除方法,它需要加上儿子的代价
dp[x][i+j][1]=min(dp[x][i+j][1],dp[x][i][1]+min(dp[ne][j][0],dp[ne][j][1]+a[ne]));

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
const int N=2e3+5;
ll dp[N][N][2],a[N];
const ll inf=1e18;
vector<int>son[N];
int siz[N];
ll tmp[N];
void dfs(int x){siz[x]=1;dp[x][0][0]=inf,dp[x][1][0]=0;//dp[x][0][1]=a[x];int f=0;for(int ne:son[x]){dfs(ne);for(int i=0;i<=siz[x]+siz[ne];i++)tmp[i]=inf;for(int i=0;i<=siz[x];i++){if(dp[x][i][0]==inf)continue;for(int j=0;j<=siz[ne];j++)tmp[i+j]=min(tmp[i+j],dp[x][i][0]+min(dp[ne][j][0],dp[ne][j][1]));}siz[x]+=siz[ne];for(int i=0;i<=siz[x];i++)dp[x][i][0]=tmp[i];}//for(int i=1;i<=siz[x];i++)dp[x][i][1]=dp[x][i][0]+a[x];//int s=vec[x].size();ll sum=0,v=0;dp[x][0][1]=a[x];siz[x]=1;for(int ne:son[x]){for(int i=0;i<=siz[x]+siz[ne];i++)tmp[i]=inf;for(int i=0;i<=siz[x];i++){if(dp[x][i][1]>=inf)continue;for(int j=0;j<=siz[ne];j++)tmp[i+j]=min(tmp[i+j],dp[x][i][1]+min(dp[ne][j][0],dp[ne][j][1]+a[ne]));}siz[x]+=siz[ne];for(int i=0;i<=siz[x];i++)dp[x][i][1]=tmp[i];}
}
int main()
{int t;scanf("%d",&t);while(t--){int n,x;scanf("%d",&n);for(int i=1;i<=n;i++)son[i].clear(),siz[i]=0;for(int i=1;i<=n;i++)for(int j=0;j<=n;j++)for(int k=0;k<=1;k++)dp[i][j][k]=inf;for(int i=2;i<=n;i++)scanf("%d",&x),son[x].push_back(i);for(int i=1;i<=n;i++)scanf("%lld",&a[i]);dfs(1);for(int i=0;i<=n;i++)printf("%lld%c",min(dp[1][i][0],dp[1][i][1])," \n"[i==n]);}return 0;
}

这篇关于第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(南京)M Monster Hunter —— 树形DP的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Javascript高级程序设计(第四版)--学习记录之变量、内存

原始值与引用值 原始值:简单的数据即基础数据类型,按值访问。 引用值:由多个值构成的对象即复杂数据类型,按引用访问。 动态属性 对于引用值而言,可以随时添加、修改和删除其属性和方法。 let person = new Object();person.name = 'Jason';person.age = 42;console.log(person.name,person.age);//'J

【第十三课】区域经济可视化表达——符号表达与标注

一、前言 地图最直接的表达就是使用符号表达。使用符号可以把简单的点线面要 素渲染成最直观的地理符号,提高地图的可读性。只要掌握了 ArcGIS 符号制 作的技巧,分析符号并总结出规则,就可以制作符合要求的地图+符号。 (一)符号的选择与修改 符号的选择在制图中至关重要,使用符号选择器对话框可从多个可用样式 中选择符号,并且每个符号都有一个标签用来描述其图形特征,如颜色或类型, 利用这些标签可

上海邀请赛 A题目 HDU 5236(dp)

先求出没有ctrl+s的时候构造长度为i的期望f[i] 。然后枚举保存的次数,求出最小即可。 #include<cstdio>#include<cstdio>#include<cmath>#include<queue>#include<stack>#include<string>#include<cstring>#include<iostream>#include<map>

poj 3160 Father Christmas flymouse 强连通+dp

首先我们可以确定的是,对于val值小于0的节点都变成0.   假设一个集合内2个房间都能任意到达,那么我就可以吧集合内的所有点的价值都取到,并且可以达到任一点。实际上集合内的每个点是相同的,这样的集合就是一个强连通分量。 那么我们就可以用tarjin算法进行强连通缩点, 最后形成一个dag的图。在dag的图上面进行dp。可以先用拓扑排序后dp。或者建反响边记忆化搜索 。 VIEW

秋招突击——6/22——复习{区间DP——加分二叉树,背包问题——买书}——新作{移除元素、实现strStr()}

文章目录 引言复习区间DP——加分二叉树个人实现 背包问题——买书个人实现参考实现 新作移除元素个人实现参考思路 找出字符串中第一个匹配项的下标个人实现参考实现 总结 引言 今天做了一个噩梦,然后流了一身汗,然后没起来,九点多才起床背书。十点钟才开始把昨天那道题题目过一遍,然后十一点才开始复习题目,为了不耽误下午的时间,所以这里的就单纯做已经做过的题目,主打一个有量,不在学

大学生自救数据结构与算法(py实现)——01递归

目录 目录 递归 基本概念 工作原理 基本要素 优点 缺点 实现技巧 实例解析:计算阶乘 斐波那契数列 高效的斐波那契数列 python中的最大递归深度 二分查找 基本原理 性能分析 优化与变体 线性递归  元素序列的递归求和 二路递归 二路递归的基本概念 典型应用 工作原理 多重递归  示例:计算卡特兰数(Catalan Number) 尾递

leetcode刷题(45)——35. 二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。” 例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5] 示例 1: 输入: root = [

MapReduce程序设计2

要求 1、数据集stock-daily,包含A股近4000只股票的今年以来的日数据;数据集stock-daily-30d仅包含最近30个交易日数据,根据自己计算机性能选择。 数据来源:https://www.joinquant.com/help/api/help?name=JQData 2、数据集stock-concept,包含A股近4000只股票所有的股票代码、名称和概念。 数据来源:万

Git使用过程中涉及的几个区域

一.  简介 Git 是一个开源的分布式版本控制系统,可以有效、高速的处理从很小到非常大的项目版本管理,也是 Linus Torvalds 为了帮助管理 Linux内核开发而开发的一个开放源码的版本控制软件。 本文简单了解一下 git涉及的几个部分,以及git 常用的命令。 二. Git涉及的三个部分 git 涉及三个区域:工作区,暂存区,本地仓库,远程版本库。 下面分别简单了解

Canvas绘制图片和区域

如何使用Canvas在图片上绘制区域? 一. 首先,我们需要初始化三个canvas画布(初始化Canvas)   initCanvas() {// 初始化canvas画布let canvasWrap = document.getElementsByClassName("canvas-wrap");this.wrapWidth = canvasWrap[0].clientWidth;thi