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

文章目录

  • 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]);}// 打家劫舍 IIIfunction<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)


写在最后

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

这款IDEA插件真的爱了

前言 Idea 是一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;它可以帮助开发人员更加高效地编写、调试和部署软件应用程序,Idea 还具有许多插件和扩展&#xff0c;可以根据开发人员的需要进行定制和扩展&#xff0c;从而提高开发效率,今天我们就来介绍一款…

基于c++版本的数据结构改-python栈和队列思维总结

##栈部分-&#xff08;叠猫猫&#xff09; ##抽象数据类型栈的定义&#xff1a;是一种遵循先入后出的逻辑的线性数据结构。 换种方式去理解这种数据结构如果我们在一摞盘子中取到下面的盘子&#xff0c;我们首先要把最上面的盘子依次拿走&#xff0c;才可以继续拿下面的盘子&…

Postman可以卸载了!这款IDEA插件太好用了!

Postman是大家最常用的API调试工具&#xff0c;那么有没有一种方法可以不用手动写入接口到Postman&#xff0c;即可进行接口调试操作&#xff1f;今天给大家推荐一款IDEA插件&#xff1a;Apipost Helper&#xff0c;写完代码就可以调试接口并一键生成接口文档&#xff01;而且还…

JIRA 禁用用户自动登录

概述 当用户登录 JIRA 时&#xff0c;他们可以通过在单击“Log In”按钮之前选中“Remember my login”复选框&#xff0c;让 JIRA 记住他们的登录信息。这样做之后&#xff0c;“Remember my login”令牌将由 JIRA 服务器存储&#xff0c;并且系统会在用户的浏览器中设置包含…

智能优化算法应用:基于学生心理学算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于学生心理学算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于学生心理学算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.学生心理学算法4.实验参数设定5.算法结果…

gitLab创建新项目

1.进入git2.选择创建项目3.勾选生成readme.md文件4.邀请成员

C //例10.1 从键盘输入一些字符,逐个把它们送到磁盘上去,直到用户输入一个“#”为止。

C程序设计 &#xff08;第四版&#xff09; 谭浩强 例10.1 例10.1 从键盘输入一些字符&#xff0c;逐个把它们送到磁盘上去&#xff0c;直到用户输入一个“#”为止。 IDE工具&#xff1a;VS2010 Note: 使用不同的IDE工具可能有部分差异。 代码块 方法&#xff1a;使用指针&…

第一篇:MongoDB的安装、启动、关闭、链接shell

目录 简介 安装 安装遇到的问题 查看brew 当前使用的源&#xff1a; 更换brew 源。更换成清华大学镜像源 版本查看 MongoDB 数据目录与日志目录 启动方式一&#xff1a; 启动MongoDB 验证MongoDB 是否正常运行 停止或重新启动 停止MongoDB 服务 重新启动MongoDB服…

身为 Go 程序员,我为啥更喜欢用 Zig?

Zig 是一种比较新的编程语言&#xff0c;于 2016 年首次推出。Zig 社区将其描述为“一种用于维护稳固的、可优化和可重用软件的通用编程语言”。 看似一句简单的描述&#xff0c;却隐藏着远大的抱负。Zig被看作是可与C语言一较高下的编程语言。此外&#xff0c;Zig 也是一个编…

Python自动化测试selenium操作下拉列表实现

处理下拉列表需要使用selenium中的工具类Select&#xff0c;常用方法如下&#xff1a; 示例网站&#xff1a;Sahi Tests 示例场景&#xff1a;打开Sahi Tests页面&#xff0c; &#xff08;1&#xff09;点击“Select Test”页面&#xff0c;鼠标点击页面中第一个下拉列表。 …

Git版本管理配置说明 - Visual Studio

一、 Git服务端配置 在源代码管理服务器新建文件夹,并配置共享访问权限Everyone(读取/写入)。 在本地访问这台服务器共享目录,确保正确打开。 在VS中打开项目,点选Git更改,点击“创建Git仓库”,创建项目初始版本。 弹出如下对话框: 因为我们只是在局域网中开发项…

LeetCode题:931下降路径最小和

目录 一、题目要求 二、解题思路 &#xff08;1&#xff09;状态表示 &#xff08;2&#xff09;状态转移方程 &#xff08;3&#xff09;初始化 &#xff08;4&#xff09;填表顺序 &#xff08;5&#xff09;返回值 三、代码 一、题目要求 931. 下降路径最小和 给你…

Web测试中文件上传测试

总体情况 功能实现&#xff1a; &#xff08;1&#xff09;文件类型正确、大小合适。 &#xff08;2&#xff09;文件类型正确&#xff0c;大小不合适。 &#xff08;3&#xff09;文件类型错误&#xff0c;大小合适。 &#xff08;4&#xff09;文件类型和大小都合适&#xff…

路由跳转添加进度条

根据npm官网的步骤&#xff1a; 1.先安装nprogress npm install nprogress 2.引入nprogress和样式文件 import nprogress from nprogress import nprogress/nprogress.css 3.在前置守卫添加进度条的展示 //全局前置守卫 router.beforeEach((to: any, from: any, next: an…

Pyside2 (Qt For Python)进度条功能实现

Pyside2 (Qt For Python)进度条功能实现 进度条&#xff08;QProgressBar&#xff09; 今天来介绍PySide2进度条&#xff08;QProgressBar&#xff09;的使用&#xff0c;如下所示&#xff1a; 说明 进度条也是一个常用的控件&#xff0c;当程序需要做一件比较耗费时间的任…

【序列化】概念及二叉树序列化、反序列化的两种方式

序列化是什么&#xff1f;为什么需要序列化&#xff1f; 前言&#xff1a; &#xff08;1&#xff09;进程想要运行&#xff0c;就要向操作系统申请内存空间&#xff0c;进程对数据的所有操作都是在内存空间中完成的。内存中有一部分数据很重要&#xff0c;我们希望将这些数据存…

Slurm集群管理系统

Slurm集群管理系统 Slurm&#xff08;Simple Linux Utility for Resource Management&#xff0c;https://slurm.schedmd.com/&#xff09;是一个开源的、容错的、高度可扩展的集群管理和作业调度系统&#xff0c;适用于大型和小型高性能计算&#xff08;HPC&#xff09;集群。…

【go语言开发】go项目打包成Docker镜像,包括Dockerfile命令介绍、goctl工具生成

本文主要介绍如何将go项目打包成镜像&#xff0c;首先介绍Dockerfile常用命令介绍&#xff0c;然后介绍使用工具goctl用于生成Dockerfile&#xff0c;还可以根据需求自定义指令内容&#xff0c;最后讲解如何将go-blog项目打包成镜像&#xff0c;以及如何运行等 文章目录 前言Do…

提高工厂能源效率的关键:工厂能耗监测平台

工业做为能源消耗的重要场所&#xff0c;所以节能减排对工业来讲是一个亟需解决的问题。除了对设备进行更新换代外&#xff0c;还需要能源管理消耗监测平台&#xff0c;帮助企业实现节能减排的目标。 工厂能源消费量非常庞大&#xff0c;能源比较难以监测与控制。传统能源的管…

【Linux】信号的保存和捕捉

文章目录 一、信号的保存——信号的三个表——block表&#xff0c;pending表&#xff0c;handler表sigset_t信号集操作函数——用户层sigprocmask和sigpending——内核层 二、信号的捕捉重谈进程地址空间&#xff08;第三次&#xff09;用户态和内核态sigaction可重入函数volat…