当前位置: 首页 > news >正文

【动态规划】【中位数】【C++算法】1478. 安排邮筒

# 作者推荐

【深度优先搜索】【树】【图论】2973. 树中每个节点放置的金币数目

本文涉及知识点

动态规划汇总

LeetCode1478. 安排邮筒

给你一个房屋数组houses 和一个整数 k ,其中 houses[i] 是第 i 栋房子在一条街上的位置,现需要在这条街上安排 k 个邮筒。
请你返回每栋房子与离它最近的邮筒之间的距离的 最小 总和。
答案保证在 32 位有符号整数范围以内。
示例 1:
输入:houses = [1,4,8,10,20], k = 3
输出:5
解释:将邮筒分别安放在位置 3, 9 和 20 处。
每个房子到最近邮筒的距离和为 |3-1| + |4-3| + |9-8| + |10-9| + |20-20| = 5 。
示例 2:
输入:houses = [2,3,5,12,18], k = 2
输出:9
解释:将邮筒分别安放在位置 3 和 14 处。
每个房子到最近邮筒距离和为 |2-3| + |3-3| + |5-3| + |12-14| + |18-14| = 9 。
示例 3:
输入:houses = [7,4,6,1], k = 1
输出:8
示例 4:
输入:houses = [3,6,14,10], k = 4
输出:0
提示:
n == houses.length
1 <= n <= 100
1 <= houses[i] <= 104
1 <= k <= n
数组 houses 中的整数互不相同。

动态规划

原理

houser[i,j]之间安装邮筒,安装到正中间的房子是最优解。
a,假定房子数是奇数,假定共有2n+1个房子。假定左边有i1个房子,右边有i2个房子。如果i1 < i2,则右移可以缩短距离;i1 > i2,则左移可以缩短距离。如果邮筒不在屋子上,则i1永远不会等于i2。i1==i2,则必定在最中间的屋子。i+(j-i)/2。
b,屋子为偶数,在中间的两坐房子之间,才会让i1和i2。其实中间两间房子的任何一间房子都可以。
可以统一为:i+(j-i)/2
确切的说 { 左边及本身的房子数小于右边的房子数,右移动。 右边及本身的房子数小于左边的房子数,左移动。 \begin{cases} 左边及本身的房子数小于右边的房子数,右移动。\\ 右边及本身的房子数小于左边的房子数,左移动。\\ \end{cases} {左边及本身的房子数小于右边的房子数,右移动。右边及本身的房子数小于左边的房子数,左移动。 → \rightarrow 稳定状态下,必须
{ i 1 > = i 2 , i 1 < = i 2 → i 1 = = i 2 邮筒不在房子上 i 1 + 1 > = i 2 , i 2 + 1 > = i 1 → a b s ( i 1 − i 2 ) < = 1 邮筒在房子上 → \begin{cases} i1 >=i2,i1 <=i2 \rightarrow i1==i2 & 邮筒不在房子上 \\ i1+1>=i2,i2+1 >= i1 \rightarrow abs(i1-i2)<=1 & 邮筒在房子上\\ \end{cases} \rightarrow {i1>=i2,i1<=i2i1==i2i1+1>=i2,i2+1>=i1abs(i1i2)<=1邮筒不在房子上邮筒在房子上
如果房子数量是奇数
{ 邮筒不在房子上 i 1 = = i 2 → ( i 1 + i 2 ) 是偶数 → 房子总数是奇数矛盾 邮筒在房子上且 i 1 等于 i 2 正中间的房子 邮筒在房子上且 i 1 和 i 2 相差 1 假定 11 + 1 = i 2 → i 1 + i 2 + 1 是偶数,和总数是奇数矛盾 → \begin{cases} 邮筒不在房子上& i1==i2 \rightarrow (i1+i2)是偶数 \rightarrow 房子总数是奇数矛盾 \\ 邮筒在房子上且i1等于i2 & 正中间的房子 \\ 邮筒在房子上且i1和i2相差1 & 假定11+1=i2 \rightarrow i1+i2+1是偶数,和总数是奇数矛盾 \\ \end{cases} \rightarrow 邮筒不在房子上邮筒在房子上且i1等于i2邮筒在房子上且i1i2相差1i1==i2(i1+i2)是偶数房子总数是奇数矛盾正中间的房子假定11+1=i2i1+i2+1是偶数,和总数是奇数矛盾 如果房子的数量是奇数则只能安装在最中间。
如果房子数量是偶数
{ 邮筒不在房子上 i 1 = = i 2 → 中间两间房子的空地 邮筒在房子上且 i 1 等于 i 2 i 1 + i 2 + 1 是奇数,与假设矛盾 邮筒在房子上且 i 1 和 i 2 相差 1 中间任意两间房子 → \begin{cases} 邮筒不在房子上& i1==i2 \rightarrow 中间两间房子的空地 \\ 邮筒在房子上且i1等于i2 & i1+i2+1是奇数,与假设矛盾 \\ 邮筒在房子上且i1和i2相差1 & 中间任意两间房子 \\ \end{cases} \rightarrow 邮筒不在房子上邮筒在房子上且i1等于i2邮筒在房子上且i1i2相差1i1==i2中间两间房子的空地i1+i2+1是奇数,与假设矛盾中间任意两间房子
如果房间数是偶数,则中间的两间房子及之间的空地都是最优解。

预处理

vDis[i][j] ,记录一个邮筒到house[i,j]的距离之和。houses要先排序。

动态规划的状态表示

dp[i][j] 表示 j个邮筒支持前i栋房最小距离。

动态规划的状态方程

通过前者状态更新后置状态。
k = 1 i + k < = h o u s e s . l e n g t h \Large_{k=1}^{i+k <= houses.length} k=1i+k<=houses.length pre[i+k][j+1] = min( ⋯ \cdots ,pre[i][j]+vDis[ ⋯ \cdots ])

动态规划的初始值

dp[0][0]=0 ,其它INT_MAX,表示非法值。

动态规划的填表顺序

i从小到大,j从小到大。

动态规划的返回值

dp.back()[k]

代码

核心代码

class Solution {
public:int minDistance(vector<int>& houses, int K) {m_c = houses.size();sort(houses.begin(), houses.end());vector<vector<int>> vDis(m_c, vector<int>(m_c));for (int center = 0; center < m_c; center++){{int iDis = 0;for (int i = center, j = center; (i >= 0) && (j < m_c); i--, j++){iDis += houses[j] - houses[i];vDis[i][j] = iDis;}}{int iDis = 0;for (int i = center, j = center + 1; (i >= 0) && (j < m_c); i--, j++){iDis += houses[j] - houses[i];vDis[i][j] = iDis;}}}vector<vector<int>> dp(m_c + 1, vector<int>(K + 1, INT_MAX));dp[0][0] = 0;for (int i = 0; i <= m_c; i++){for (int j = 0; j < K; j++){if (INT_MAX == dp[i][j]){continue;}for (int m = 1; m + i <= m_c; m++){dp[m + i][j + 1] = min(dp[m + i][j + 1],dp[i][j]+vDis[i][i+m-1]);}}}return dp.back().back();}int m_c;
};

测试用例

template<class T>
void Assert(const T& t1, const T& t2)
{assert(t1 == t2);
}template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){Assert(v1[i], v2[i]);}}int main()
{	vector<int> houses;int k;{Solution sln;houses = { 7,4,6,1 };k = 1;auto res = sln.minDistance(houses, k);Assert(8, res);}{Solution sln;houses = { 1, 4, 8, 10, 20 };k = 3;auto res = sln.minDistance(houses, k);Assert(5, res);}{Solution sln;houses = { 2,3,5,12,18 };k = 2;auto res = sln.minDistance(houses, k);Assert(9, res);}{Solution sln;houses = { 3,6,14,10 };k = 4;auto res = sln.minDistance(houses, k);Assert(0, res);}
}

2023年2月版

class Solution {
public:
int minDistance(vector& houses, int k) {
const int iNotMay = 1000 * 1000 * 10;
std::sort(houses.begin(), houses.end());
m_c = houses.size();
vector pre(m_c);
for (int i = 0; i < m_c; i++)
{
pre[i] = Cost(houses, 0, i + 1);
}
for (int iK = 2; iK <= k; iK++)
{
vector dp(m_c, iNotMay);
for (int iHouse = 0; iHouse < houses.size(); iHouse++)
{
for (int pr = 0; pr < iHouse; pr++)
{
if (iNotMay == pre[pr])
{
continue;
}
dp[iHouse] = min(dp[iHouse], pre[pr] + Cost(houses, pr+1, iHouse + 1));
}
}
pre.swap(dp);
}
return pre.back();
}
int Cost(const vector& houses,int left, int r)
{
int iCost = 0;
int iMean = houses[left + (r - left) / 2];
for (int i = left; i < r; i++)
{
iCost += abs(houses[i] - iMean);
}
return iCost;
}
int m_c;
};

2023年7月版

class Solution {
public:
int minDistance(vector& houses, int k) {
m_c = houses.size();
sort(houses.begin(), houses.end());
vector<vector> vCost(m_c, vector(m_c));
for(int i= 0 ;i < m_c; i++ )
for (int j = i+1; j < m_c; j++)
{
int iMidValue = houses[i] + (houses[j] - houses[i]) / 2;
int cost = 0;
int k = i+1;
for (; houses[k] <= iMidValue; k++)
{
cost += houses[k] - houses[i];
}
for (; k < j; k++)
{
cost += houses[j] - houses[k];
}
vCost[i][j] = cost;
}
const int iNotMay = 1000 * 1000 * 10;
vector<vector> dp(m_c + 1, vector(k + 1, iNotMay));
dp[0][0] = 0;
dp[0][1] = 0;
vector vBegin(m_c);
{
int iSum = 0;
for (int i = 1; i < m_c; i++)
{
iSum += (houses[i] - houses[i - 1]) * i;
vBegin[i] = iSum;
}
}
for (int i = 1; i < m_c; i++)
{
for (int prePos = 0; prePos < i; prePos++)
{
for (int preK = 0; preK < k; preK++)
{
if (iNotMay == dp[prePos][preK])
{
continue;
}
if (0 == preK)
{
dp[i][preK + 1] = vBegin[i];
continue;
}
dp[i][preK + 1] = min(dp[i][preK + 1],dp[prePos][preK] + vCost[prePos][i]);
}
}
}
vector vEnd(m_c);
{
int iSum = 0;
for (int i = m_c - 2; i >= 0; i–)
{
iSum += (houses[i + 1] - houses[i]) * (m_c - 1 - i);
vEnd[i] = iSum;
}
}
int iRet = iNotMay;
for (int i = k-1; i < m_c; i++)
{
iRet = min(iRet, dp[i][k] +vEnd[i]);
}
return iRet;
}
int m_c;
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

相关文章:

【动态规划】【中位数】【C++算法】1478. 安排邮筒

# 作者推荐 【深度优先搜索】【树】【图论】2973. 树中每个节点放置的金币数目 本文涉及知识点 动态规划汇总 LeetCode1478. 安排邮筒 给你一个房屋数组houses 和一个整数 k &#xff0c;其中 houses[i] 是第 i 栋房子在一条街上的位置&#xff0c;现需要在这条街上安排 k…...

C#系列-数据结构+递归算法+排序算法(3)

C#数据结构 在C#中&#xff0c;数据结构是用于组织和管理数据的方式&#xff0c;以便更有效地进行数据的存储、访问和操作。数据结构对于算法的性能和设计至关重要&#xff0c;因为它们决定了数据如何在内存中布局以及如何与算法进行交互。C#提供了许多内置的数据结构&#xf…...

Redis实现秒杀

前期准备 缓存选择考虑 Redis和Redis Cluster&#xff08;分布式版本&#xff09;&#xff0c;是一个分布式缓存系统。其支持多种数据结构&#xff0c;也支持MQ。Redis在性能上做了大量优化。因此使用Redis或者Redis Cluster就可以轻松实现一个强大的秒杀系统。 用Redis的这…...

4 scala集合-Map

和 Java 一样&#xff0c;Scala 也有表示键值对&#xff08;Key-Value&#xff09;集合的 Map 数据结构。同样&#xff0c;Map 也分不可变和可变&#xff0c;不可变需要使用类 scala.collection.mutable.Map。 1 不可变 Map 可以使用以下语法定义不可变 Map 对象 val/var ma…...

QT 对象树模型

QObject是Qt里边绝大部分类的根类 QObject对象之间是以对象树的形式组织起来的。 当两个QObject&#xff08;或子类&#xff09;的对象建立了父子关系的时候。子对象就会加入到父对象的一个成员变量叫children&#xff08;孩子&#xff09;的list&#xff08;列表&#xff09;…...

ubuntu快速安装miniconda

ubuntu快速安装miniconda 环境 ubuntu.22.04 显卡 RTX 3050 关于选择Miniconda还是Anaconda的问题&#xff0c;Anaconda安装包比较大&#xff0c;耗时比较长&#xff0c;如果你是绝对的初学者&#xff0c;选择Anaconda会比较稳妥一些&#xff1b;否则建议你还是选择Miniconda安…...

阿里云游戏服务器多少钱一年?

阿里云游戏服务器租用价格表&#xff1a;4核16G服务器26元1个月、146元半年&#xff0c;游戏专业服务器8核32G配置90元一个月、271元3个月&#xff0c;阿里云服务器网aliyunfuwuqi.com分享阿里云游戏专用服务器详细配置和精准报价&#xff1a; 阿里云游戏服务器租用价格表 阿…...

小游戏和GUI编程(7) | SimpleNN 界面源码解析

小游戏和GUI编程(7) | SimpleNN 界面源码解析 0. 简介 SimpleNN 是 AdamYuan 在高中一年级时用 1 天时间写出来的简易 CNN, 使用 SFML 做 UI, 用于交互式输入手写数字&#xff0c;这个数字被训练好的 CNN 网络执行推理得到识别结果, 它的运行效果如下&#xff1a; 这一篇我们…...

c++设计模式之代理模式

作用 代理模式主要用于&#xff0c;通过代理类&#xff0c;来控制实际对象的访问权限 案例 class VideoSite { public:virtual void freeVideo()0;virtual void vipVideo()0;virtual void trickVideo()0; };class FixBugVideoSite:public VideoSite { public:void freeVideo()…...

第5个-模糊加载

Day 5 - Blurry Loading 1. 项目展示 2. 分析思路 变化过程 数字从 0 不断增长到 100&#xff1b;中间的百分比数字逐渐消失&#xff0c;即透明度 opacity 从 1 到 0&#xff1b;背景图片从模糊变为清晰&#xff0c;滤镜 filter.blur()的参数设置为从 30px 到 0px。 小 tips…...

rtt设备io框架面向对象学习-adc设备

目录 1.adc设备基类2.adc设备基类的子类3.初始化/构造流程3.1设备驱动层3.2 设备驱动框架层3.3 设备io管理层 4.总结5.使用 1.adc设备基类 此层处于设备驱动框架层。也是抽象类。 在/ components / drivers / include / drivers 下的adc.h定义了如下adc设备基类 struct rt_ad…...

面试官:介绍一下Exception和Error之间的区别

前言 大家好&#xff0c;我是chowley&#xff0c;在我之前的面试中&#xff0c;遇到过这样一个问题&#xff1a;Exception和Error之间有什么区别&#xff1f;今天我就来好好地总结一下&#xff01; 主体 在Java编程中&#xff0c;Exception和Error都是Java中的可抛出对象&am…...

【RabbitMQ(一)】:基本介绍 | 配置安装与快速入门

应该是新年前最后一篇博客了&#xff0c;明天浅浅休息一下&#xff0c;提前祝大家新年快乐捏&#xff01;&#x1f60a;&#x1f60a;&#x1f60a; 01. 基础理解 1.1 同步调用和异步调用 &#x1f449; 同步调用 的时候调用者会 阻塞 等待被调用函数或方法执行完成&#xff…...

ElasticSearch之search API

写在前面 本文看下查询相关内容&#xff0c;这也是我们在实际工作中接触的最多的&#xff0c;所以有必要好好学习下&#xff01; 1&#xff1a;查询的分类 主要分为如下2类&#xff1a; 1:基于get查询参数的URI search 2&#xff1a;基于post body的request body search&am…...

07-Java桥接模式 ( Bridge Pattern )

Java桥接模式 摘要实现范例 桥接模式&#xff08;Bridge Pattern&#xff09;是用于把抽象化与实现化解耦&#xff0c;使得二者可以独立变化 桥接模式涉及到一个作为桥接的接口&#xff0c;使得实体类的功能独立于接口实现类&#xff0c;这两种类型的类可被结构化改变而互不影…...

golang集成sentry: go-redis

网上没有找到go-redis集成sentry的库&#xff0c; 所以我简单实现了一个 代码&#xff1a; https://github.com/Shujie-Tan/go-redis-sentry 使用方法&#xff1a; import (redis_sentry "github.com/Shujie-Tan/go-redis-sentry" ) rdb : redis.NewClient(&re…...

用EXCEL从地址(上海)中提取各区(浦东新区等区)信息

背景&#xff1a; 朋友工作需要经常用EXCEL把各上海用户收货地址中的区提取出来&#xff0c;之前一直手动处理&#xff0c;希望我帮忙用EXCEL公式直接提取处理。 数据样式&#xff1a; 中国上海市浦东新区A小区 上海徐汇区B小区 中国&#xff0c;上海&#xff0c;浦东新区&a…...

关于在分布式环境中RVN和使用场景的介绍3

简介 在《关于在分布式环境中RVN和使用场景的介绍2》和《关于在分布式环境中RVN和使用场景的介绍1》中我们介绍了RVN的概念和在一些具体用例中的使用。在本文中我们讨论一下在分布式环境中使用RVN需要注意的问题。 问题 我们在收到一条待处理的事件时&#xff0c;需要检查该…...

计算最小公倍数math.lcm()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 计算最小公倍数 math.lcm() 请问以下代码输出的结果是&#xff1f; import math print("【执行】math.lcm(2, 4)") print(math.lcm(2, 4)) print("【执行】math.lcm(1, 2, 3…...

VUE SEO 几种方案经典面试题

1、SSR服务器渲染 Vue.js 是构建客户端应用程序的框架。默认情况下&#xff0c;可以再浏览器中输出Vue组件&#xff0c;进行生成DOM和操作DOM。然而&#xff0c;也可以将同一个组件渲染未服务器端的HTML字符串&#xff0c;将它们直接发送到浏览器&#xff0c;最后将这些静态标…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成

厌倦手动写WordPress文章&#xff1f;AI自动生成&#xff0c;效率提升10倍&#xff01; 支持多语言、自动配图、定时发布&#xff0c;让内容创作更轻松&#xff01; AI内容生成 → 不想每天写文章&#xff1f;AI一键生成高质量内容&#xff01;多语言支持 → 跨境电商必备&am…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险

C#入门系列【类的基本概念】&#xff1a;开启编程世界的奇妙冒险 嘿&#xff0c;各位编程小白探险家&#xff01;欢迎来到 C# 的奇幻大陆&#xff01;今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类&#xff01;别害怕&#xff0c;跟着我&#xff0c;保准让你轻松搞…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...