[Daimayuan] 树(C++,动态规划,01背包方案数)
有一棵 n n n 个节点的以 1 1 1 号点为根的有根树。现在可以对这棵树进行若干次操作,每一次操作可以选择树上的一个点然后删掉连接这个点和它的儿子的所有边。
现在我们想知道对于每一个 k k k ( 1 ≤ k ≤ n 1≤k≤n 1≤k≤n),最少需要多少次操作能让图中恰好存在 k k k 个联通块。
输入格式
第一行输入一个正整数 n n n。
第二行输入 n − 1 n−1 n−1 个整数 f 1 , f 2 , . . . , f n − 1 f_1,f_2,...,f_{n−1} f1,f2,...,fn−1, f i f_i fi 表示 i + 1 i+1 i+1 号点的父亲,保证 1 ≤ f i ≤ i 1≤f_i≤i 1≤fi≤i。
输出格式
输出 n n n 个整数,第 i i i 个数表示 k = i k=i k=i 时的答案,如果无法让图中恰好存在 i i i 个联通块,则输出 -1
。
样例输入1
6
1 2 1 1 2
样例输出1
0 -1 1 1 -1 2
数据规模
共 10 10 10 个测试点。
测试点 1 , 2 , 3 1,2,3 1,2,3 满足 n ≤ 20 n≤20 n≤20。
测试点 4 , 5 , 6 4,5,6 4,5,6 满足 n ≤ 100 n≤100 n≤100。
对于所有数据,满足 1 ≤ n ≤ 3000 1≤n≤3000 1≤n≤3000。
解题思路
对于一棵树来说,删去任意一条边都会使连通块数目 + 1 +1 +1。
那么要判断能否得到 k k k个连通块,我们只需要判断能否恰好删去 k − 1 k-1 k−1条边。
题目要求操作为:删除一个节点与子节点之间的所有边。
那么统计每个节点的子节点数目,然后就变为了01背包可行性问题:
每一个节点都是一个物品,问能否恰好装满容量为 k − 1 k-1 k−1的背包?
for (int i = 1; i <= n; i++) {//尝试每一个物品for (int j = 0; j < n; j++) {//尝试新的重量组合if (j - items[i] >= 0)ans[i][j] = ans[i - 1][j] || ans[i - 1][j - items[i]];elseans[i][j] = ans[i - 1][j];}
}
以上我们只是检验了可行性问题,但是题目中还有另外一个要求:操作次数最少。
因为在物品组合中没有先后顺序,所以我们可以通过物品组合中的物品数量来确定操作次数。
只有新的操作次数小于旧的操作次数的时候,我们才进行更新。
for (int i = 1; i <= n; i++) {//尝试每一个物品for (int j = 0; j < n; j++) {//尝试新的重量组合if (j - items[i] >= 0 && ans[i - 1][j] && ans[i - 1][j - items[i]])ans[i][j] = min(ans[i - 1][j], ans[i - 1][j - items[i]] + 1);else if (ans[i - 1][j])ans[i][j] = ans[i - 1][j];else if (j - items[i] >= 0 && ans[i - 1][j - items[i]])ans[i][j] = ans[i - 1][j - items[i]];}
}
注:1)以上代码段中,ans
中元素的含义发生了变化:可行/不可行 -> 物品数量;
2)为了与不存在的组合(ans[i][j] = 0
)相区分,我们为所有存在的组合物品数量添加偏置bias
,也就是说,物品数量 = ans[i][j] - bias
。
以上代码的空间复杂度、时间复杂度均可以接受,可以AC,接下来是优化部分qwq。
因为嫌弃这个算法的空间复杂度,所以我们对其进行优化,压缩到二维数组:
for (int i = 1; i <= n; i++) {//尝试每一个物品for (int j = 0; j < n; j++) {//尝试新的重量组合if (j - items[i] >= 0 && ans[(i - 1) % 2][j] && ans[(i - 1) % 2][j - items[i]])ans[i % 2][j] = min(ans[(i - 1) % 2][j], ans[(i - 1) % 2][j - items[i]] + 1);else if (ans[(i - 1) % 2][j])ans[i % 2][j] = ans[(i - 1) % 2][j];else if (j - items[i] >= 0 && ans[(i - 1) % 2][j - items[i]])ans[i % 2][j] = ans[(i - 1) % 2][j - items[i]];}
}
还是嫌弃?继续压,压缩到一维数组:
for (int i = 1; i <= n; i++) {//尝试每一个物品for (int j = n; j >= items[i]; j--) {//尝试新的重量组合if (j - items[i] >= 0 && ans[j] && ans[j - items[i]])ans[j] = min(ans[j], ans[j - items[i]] + 1);else if (ans[j]) ans[j] = ans[j];else if (j - items[i] >= 0 && ans[j - items[i]])ans[j] = ans[j - items[i]] + 1;}
}
然后我们删除一些无用的部分:
for (int i = 1; i <= n; i++) {//尝试每一个物品for (int j = n; j >= items[i]; j--) {//尝试新的重量组合if (ans[j] && ans[j - items[i]]) ans[j] = min(ans[j], ans[j - items[i]] + 1);else if (ans[j - items[i]]) ans[j] = ans[j - items[i]] + 1;}
}
嗯,好看多了qwq。
最后,AC代码如下:
#include <iostream>
using namespace std;
const int max_n = 3000;int ans[max_n + 1], n;
int items[max_n + 1];int main() {cin >> n;int fa;for (int i = 1; i < n; i++) {cin >> fa;items[fa]++;}int bias = 1;ans[0] = bias;for (int i = 1; i <= n; i++) {//尝试每一个物品for (int j = n; j >= items[i]; j--) {//尝试新的重量组合if (ans[j] && ans[j - items[i]]) ans[j] = min(ans[j], ans[j - items[i]] + 1);else if (ans[j - items[i]]) ans[j] = ans[j - items[i]] + 1;}}cout << 0;for (int i = 2; i <= n; i++) {cout << ' ' << ans[i - 1] - bias;}return 0;
}
相关文章:
[Daimayuan] 树(C++,动态规划,01背包方案数)
有一棵 n n n 个节点的以 1 1 1 号点为根的有根树。现在可以对这棵树进行若干次操作,每一次操作可以选择树上的一个点然后删掉连接这个点和它的儿子的所有边。 现在我们想知道对于每一个 k k k ( 1 ≤ k ≤ n 1≤k≤n 1≤k≤n),最少需要多少次操作能…...
如何选择源代码加密软件
(SDC沙盒)和DLP、文档加密、云桌面等,其优缺点做客观比较如下: 比较内容安全容器(SDC沙盒)DLP文档加密云桌面代表厂家*信达卖咖啡、赛门贴科亿*通、IP噶德、*盾、*途四杰、深*服设计理念以隔离容器加准入技术为基础,构…...
TO-B类软件产品差异化
产品差异化,是在市场众多同质化产品中,突出自身产品亮点的重要方式。对于客户来讲其选择是多种多样的,与其花费大量的时间研究每一家产品的特点,还不如直接选择品牌更大、价格更低的产品来的直接,因此显而易见的突出产…...

设计模式之美-实战一(上):业务开发常用的基于贫血模型的MVC架构违背OOP吗?
领域驱动设计(Domain Driven Design,简称DDD)盛行之后,这种基于贫血模型的传统的开发模式就更加被人诟病。而基于充血模型的DDD开发模式越来越被人提倡。所以,我打算用两节课的时间,结合一个虚拟钱包系统的…...
ChatGPT如何训练自己的模型
ChatGPT是一种自然语言处理模型,它的任务是生成自然流畅的对话。如果想要训练自己的ChatGPT模型,需要进行大量的数据收集、预处理、配置训练环境、模型训练、模型评估等过程。本文将详细介绍这些过程,帮助读者了解如何训练一个高品质的ChatGP…...
springboot使用线程池的实际应用(一)
在实际Spring Boot项目中,我们可以使用Java的原生多线程或者使用Spring自带的线程池进行多线程编程。多线程的好处在于能够提高应用程序的运行效率,特别是在某些计算密集型场景下。以下是一些使用多线程的典型场景: 并发处理请求:…...
ESP-8266学习笔记
1、学习地址 【XMF09F系列资源】基于MicroPython的ESP8266物联网应用开发-赛教资源目录汇总-小蜜蜂笔记 Quick reference for the ESP8266 — MicroPython latest documentation 2、MicroPython及相关开发资源 3、固件烧录与uPyLoader的使用 烧录教程参考: https://www.…...
Java泛型简单的使用
前言 Java里面的泛型在实际开发中运用的很多,学过C的同学一定知道C的模板,而Java中的泛型,一定程度上和它还是挺像的。 相信写Java的人,大都有用过List的实现类ArrayList。在Java没有泛型之前,它的内部是一个Object的…...

深度探索:Qt CMake工程编译后的自动打包策略
深度探索:Qt CMake工程编译后的自动打包策略 1. 引言(Introduction)1.1 Qt和CMake的基本概念(Basic Concepts of Qt and CMake)1.2 自动打包的重要性(Importance of Automatic Packaging) 2. Qt…...

2.7 编译型和解释型
2.7 编译型和解释型 前面我们使用java和javac命令把Hello,World!在控制台输出。那为什么输出,这里我们需要掌握两个知识点。编译型语言和解释型语言。在计算机的高级编程语言就分为编译型语言和解释型语言。而我们的Java既有编译型的特点也有…...

校园网自动登陆(河南科技学院)
1. 介绍 河南科技学院校园网自动登陆(新乡的很多系统相似,可能也可以用?),java版。可以实现电脑,路由器,软路由的自动认证wifi,后续会上传docker版本的。 源码地址 github:https://…...
C++11 override和final关键字
C11中的override和final关键字是为了增强代码的编译时类型检查和面向对象设计中的继承机制。 override关键字用于显示地表明派生类中的成员函数覆盖了基类中的虚函数。当派生类中的函数与基类中的虚函数签名不同或者没有使用override关键字时,编译器会给出警告或错…...
kafka的log存储解析
kafka的log存储解析——topic的分区partition分段segment以及索引等 引言Kafka中的Message是以topic为基本单位组织的,不同的topic之间是相互独立的。每个topic又可以分成几个不同的partition(每个topic有几个partition是在创建topic时指定 的),每个…...

4.文件系统
组成 Linux:一切皆文件 索引节点(I-node) I-node(Index Node):文件系统的内部数据结构,用于管理文件的元数据和数据块。 文件的元数据:包括文件的权限、拥有者、大小、时间戳、索引…...
Shell脚本case in esac分支语句应用
记录:434 场景:Shell脚本case in esac分支语句应用。 版本:CentOS Linux release 7.9.2009。 1.case in esac格式 格式: case 值 in 模式1)expression;; 模式2)expression;; 模式n)expression;; esac 解析:case…...

【线性dp必学四道题】线性dp四道经典例题【最长上升子序列】、【最长公共子序列】、【最长公共上升子序列(maxv的由来)】【最长公共子串】
【最长上升子序列】、【最长公共子序列】、【最长公共上升子序列】 最长上升子序列f[i] 表示以i结尾的最长子序列 最长公共子序列f[i][j] 表示 a前i 和 b前j个 最长公共长度 最长公共上升子序列f[i][j]代表所有a[1 ~ i]和b[1 ~ j]中以b[j]结尾的公共上升子序列的集合 最长公共子…...

追寻幸福:探索幸福的关键特征和行为
目录 1. 积极的心态 2. 良好的人际关系 3. 自我接纳和自尊 4. 追求意义和目标 5. 健康的身心状态 6. 感知和实现个人价值 幸福是一个主观的感受,因此不同的人对于幸福的定义和追求方式可能会有所不同。然而,有一些共同的特点和行为模式,…...
Redis-02-集群
一、redis5搭建集群 1.1、案例:搭建6台redis主机,配置如下 redis并发量:https://www.gxlcms.com/redis-350423.html主机IP:192.168.168.60~65修改redis配置文件hash槽移动,槽内的数据也随之移动 [root60 ~]# vim /e…...

【2023 · CANN训练营第一季】MindSpore模型快速调优攻略 第三章——MindSpore云上调试调优
1.ModelArts云上调试调优 ModelArts密钥初始化 详细教程: 初始化OBS服务 创建训练作业 2.MindSpore IDE插件效率提升 通过智能代码块推荐、代码自动补全等特性,提升MindSpore脚本开发效率,对接ModelArts云服务,实现模型训…...

python笔记17_实例演练_二手车折旧分析p2
…… 书接上文 4.车辆等级维度 探查车龄为5年的车辆,折旧价值与车辆等级的关系。 # 筛选出车龄为5的数据创建新表 data_age5 data[data[age] 5] data_age5 # 分组聚合计算均值 data_car_level data_age5.groupby(car_level_name)[lowest_price].mean().reset…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...
十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建
【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...