【每日一题】最小化旅行的价格总和

文章目录

  • Tag
  • 题目来源
  • 题目解读
  • 解题思路
    • 方法一:深搜+动态规划
  • 写在最后

Tag

【深搜+动态规划】【树】【2023-12-06】


题目来源

2646. 最小化旅行的价格总和


题目解读

有一棵无向、无根的树,树中的节点从 0 到 n-1,每个节点有一个关联的价格,你可以把不相邻节点的关联价格减半,现在要从一些节点到另一些节点称为旅行(各自独立的),返回执行所有旅行的最小代价总和。


解题思路

一开始的想法是这样的,如果没有 「减半」操作,那这道题目就是最短路径问题。但是有了「减半」就无从下手了。

方法一:深搜+动态规划

思路

为了使旅行的价格总和最小,每次旅行的路径必须是最短路径。因此,我们每次从旅行的起点 trip[i][0] 出发,需要「朝向」终点 trip[i][1] 前进,这个「朝向」我们用一个深搜(递归)来实现。

在深搜过程中我们将经过节点的次数记录下来,后续就可以根据经过节点的次数来计算旅行的价格。并且,这样可以方便后续的「减半」操作。

题目中说的 「选择一些 非相邻节点 并将价格减半」,换言之,如果一个节点减半了,那么其下一个节点(子节点或者父节点)不能减半,如果一个节点没有减半,那么其下一个节点(子节点或者父节点)可以减半。在这样的情况下,计算最小旅行价格。

本节点的选择可能会影响到相邻节点的选择,这不就是动态规划问题吗?相应的题目为 337. 打家劫舍 III。

在 打家劫舍 问题中,给出的是一棵二叉树,可以从根节点开始进行动态规划,本题是一个无向图,可以随意选择一个节点作为根节点进行动态规划。我们选择从节点 0 出发在树上进行动态规划,对于节点 x 及其儿子 y 需要分类讨论:

  • 如果 prices[x] 不变,那么 prices[y] 可以减半,也可以不减半,取二者最小值;
  • 如果 prices[x] 减半,那么 prices[y] 只能不变。

因此,子树 x 需要返回两个值:

  • prices[x] 不变时的子树 x 的最小代价总和;
  • prices[x] 减半时的子树 x 的最小代价总和。

最终的答案就是,以 0 作为根节点,减半或者不减半时的最小旅行价格。

算法

在具体实现中:

  • 首先,建立无向图;
  • 接着,递归更新记录节点次数的数组;
  • 然后,在树上进行动态规划;
  • 最后,返回以 0 为根的最小旅行代价。
class Solution {
public:
    int minimumTotalPrice(int n, vector<vector<int>>& edges, vector<int>& price, vector<vector<int>>& trips) {
        vector<vector<int>> g(n);
        // 建树
        for (auto edge : edges) {
            int x= edge[0], y = edge[1];
            g[x].push_back(y);
            g[y].push_back(x);
        }

        vector<int> cnts(n);    // 存放节点的次数
        function<bool(int, int, int)> dfs = [&](int x, int pa, int end)->bool {
            if (x == end) {
                cnts[x] += 1;
                return true;
            }

            for (int y : g[x]) {
                if (y != pa && dfs(y, x, end)) {
                    cnts[x] += 1; // x 是朝向 end 前进的,记录
                    return true;
                }
            }
            return false;
        };
        for (auto& trip : trips) {
            dfs(trip[0], -1, trip[1]);
        }

        // 打家劫舍 III
        function<pair<int, int>(int, int)> dp = [&](int x, int pa) -> pair<int, int> {
            int not_halve = price[x] * cnts[x];     // x 不变
            int halve = not_halve / 2;              // x 减半

            for (int y : g[x]) {
                if (y != pa) {
                    auto [nh, h] = dp(y, x);        // y 不变与 y 减半
                    not_halve += min(nh, h);        // x 不变,y 取不变与变中的较小值
                    halve += nh;                    // x 减半,y 只能不变
                }
            }
            return {not_halve, halve};
        };
        
        auto [nh, h] = dp(0, -1);
        return min(nh, h);
    }
};

复杂度分析

时间复杂度: O ( n m ) O(nm) O(nm),其中 m m m t r i p s trips trips 的长度。

空间复杂度: O ( n ) O(n) O(n)


写在最后

如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。

最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 👍 哦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/222537.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【AntDB 数据库】国产数据库肇始之独具特色的场景需求

影响国产数据库源起、发展的因素有很多&#xff0c;除了数据库本身对国家和组织的重要战略性地位、市场趋势向好等因素外&#xff0c;还有哪些关键因素呢&#xff1f;今天AntDB数据库就跟大家一起回顾、探求一下我国最早一批国产数据库起源背后独具特色的场景需求。 过去40年&…

C++红黑树封装set和map(很详细)

前言 在前面&#xff0c;我们学习了红黑树。&#xff08;没学过红黑树直接看会很吃力&#xff09;set和map的底层就是红黑树&#xff0c;现在我们要用这棵树来封装STL里面的容器&#xff1a;set和map。 下面是之前讲过的红黑树&#xff0c;他只是普通的“Key”模型,适合封装set…

技术博客:Vue中各种混淆用法汇总

技术博客&#xff1a;Vue中各种混淆用法汇总 摘要 本文主要介绍了在Vue中使用的一些常见混淆用法&#xff0c;包括new Vue()、export default {}、createApp()、Vue.component、Vue3注册全局组件、Vue.use()等&#xff0c;以及如何使用混淆器对代码进行加固&#xff0c;保护应…

Opencv库如何检测图片中鸡蛋数量

Opencv库检测图片中鸡蛋数量 由于需要写一个检测鸡蛋数量的程序&#xff0c;用了几个opencv中的经典方法&#xff0c;实现了图片中鸡蛋的检测。在一步步实现的同时&#xff0c;同时说明每个方法的用途。希望能给学习opencv的小伙伴一些帮助。下图为原始图和实现后的检测边框。…

csdn-添加目录

只需一句&#xff0c;根据文章标题层级自动生成目录 在文章内添加下面这句会自动生成目录 [TOC](此处填写目录的标题)

【CMake入门】第一节——CMake的安装与简单样例

CMake——Cross platform Make CMake是一个开源的跨平台自动化建构系统&#xff0c;用来管理程序构建&#xff0c;不相依于特定编译器&#xff0c;不用亲自编写Makefile。需要编写CMakeList.txt文件来定制整个编译流程可以自动化编译源代码、创建库、生成可执行二进制文件等 …

msvcr110.dll丢失的解决方法有哪些-常见方法教程

我们在日常使用电脑中经常遇到各种问题&#xff0c;比如系统文件丢失是最常见的&#xff0c;其中msvcr110.dll丢失也是非常常见的问题&#xff0c;那么msvcr110.dll文件为什么会丢失&#xff0c;丢失对电脑有什么影响呢&#xff0c;丢失了有什么解决方法&#xff1f;今天小编就…

【MySQL】聚合函数和分组(查找)

聚合函数分组分组聚合如何显示每个部门的平均工资和最高工资显示每个部门的每种岗位的平均工资和最低工资显示平均工资低于2000的部门和它的平均工资(SMITH员工不参与)where 和 having 的区别 聚合函数 函数说明COUNT([DISTINCT] expr)返回查询到的数据的 数量SUM([DISTINCT] …

深度学习助力手写识别OCR软件的发展与应用

随着人工智能和深度学习技术的不断发展&#xff0c;手写识别OCR软件的技术也在不断进步。目前&#xff0c;市场上已经有一些基于深度学习的手写识别OCR软件&#xff0c;可以对手写文字进行自动识别和转换。 首先&#xff0c;我们来介绍一下基于深度学习的手写识别OCR软件的基本…

C语言能判断一个变量是int还是float吗?

C语言能判断一个变量是int还是float吗&#xff1f; 在开始前我有一些资料&#xff0c;是我根据自己从业十年经验&#xff0c;熬夜搞了几个通宵&#xff0c;精心整理了一份「C语言从专业入门到高级教程工具包」&#xff0c;点个关注&#xff0c;全部无偿共享给大家&#xff01;&…

Qnx boot workflow

S820A QNX Hypervisor Software User Guide 80-CF838-1 Rev. Img 生成脚本: target/hypervisor/host/create_images.sh tools/build/image-builder.sh The QVM config file for the guest is instantiated within the host rootfs build file, located at root/target/hyp…

python和php语言编写大型爬虫那个更适用 ?

以我多年从事爬虫行业的经验来说&#xff0c;其实python和php两种语言都可以用于编写大型爬虫项目&#xff0c;但是因为Python语言简洁方便&#xff0c;第三方库相比有很多&#xff0c;数据处理能力也很强&#xff0c;所以受到大多数程序员的追捧。 Python和PHP都可以用于编写…

多平台展示预约的服装小程序效果如何

线下实体服装店非常多&#xff0c;主要以同城生意为主&#xff0c;但随着电商经济增长&#xff0c;传统线下自然流量变少&#xff0c;商家们会选择线上入驻平台开店获得更多线上用户&#xff0c;包括自建私域小程序等。 而除了直接卖货外&#xff0c;线上展示预约在服装行业也…

人工智能-机器翻译:技术发展与代码实战

在本文中&#xff0c;我们深入探讨了机器翻译的历史、核心技术、特别是神经机器翻译&#xff08;NMT&#xff09;的发展&#xff0c;分析了模型的优化、挑战及其在不同领域的应用案例。同时&#xff0c;我们还提出了对未来机器翻译技术发展的展望和潜在的社会影响。 关注TechLe…

class049 滑动窗口技巧与相关题目【算法】

class049 滑动窗口技巧与相关题目【算法】 算法讲解049【必备】滑动窗口技巧与相关题目 code1 209. 长度最小的子数组 // 累加和大于等于target的最短子数组长度 // 给定一个含有 n 个正整数的数组和一个正整数 target // 找到累加和 > target 的长度最小的子数组并返回…

docker配置阿里云镜像加速器

docker配置阿里云镜像加速器 1.注册一个阿里云账户 https://cr.console.aliyun.com/ 2.获取加速器地址链接 可直接复制&#xff0c;位置如下: 3.配置脚本 这个位置可以直接复制脚本&#xff0c;大家操作的时候直接复制自己的就好 sudo mkdir -p /etc/docker sudo tee /et…

应用于指纹门锁上的安全芯片ACM32FP421系列,内核性能高,安全性高,内建 AES、CRC、TRNG 等算法模块

ACM32FP421 芯片的内核基于 ARMv8-M 架构&#xff0c;支持 Cortex-M33 和 Cortex-M4F 指令集。内核支持一 整套 DSP 指令用于数字信号处理&#xff0c;支持单精度 FPU 处理浮点数据&#xff0c;同时还支持 Memory Protection Unit &#xff08;MPU&#xff09;用于提升应用的安…

数字化未来,亚马逊鲲鹏系统引领全新购物下单体验

随着科技的不断发展&#xff0c;人们的购物方式也在发生翻天覆地的变化。在这个数字化时代&#xff0c;亚马逊鲲鹏系统应运而生&#xff0c;成为一款集注册、买家号智能养号、自动下单、自动留评、QA等功能于一体的综合软件&#xff0c;为用户提供了全新的购物体验。 首先&…

RocketMQ-源码架构二

梳理一些比较完整&#xff0c;比较复杂的业务线 消息持久化设计 RocketMQ的持久化文件结构 消息持久化也就是将内存中的消息写入到本地磁盘的过程。而磁盘IO操作通常是一个很耗性能&#xff0c;很慢的操作&#xff0c;所以&#xff0c;对消息持久化机制的设计&#xff0c;是…

单片机的基本概念——什么是单片机、单片机的分类以及单片机的发展历史、发展趋势

什么是单片机 本文主要涉及了什么是单片机、单片机的分类、单片机发展史以及单片机的发展趋势的一些内容 文章目录 什么是单片机一、 什么是单片机1.1 微型计算机1.2 单板机1.3 单片机1.3.1 单片机的分类 二、 单片机的发展历史2.1 发展阶段2.2 单片机的特点2.3 单片机的发展趋…