题解:P2803 学校选址 II

医院选址问题--数据结构课程设计 2019年12月份的课程设计。 问题描述: n个村庄之间的路径用有向加权图表示,要从这n个村庄中选择一个村庄建立一所医院,问这所医院应建在哪个村庄,能使所有的村庄都离这家医院最近(能使离医院最远的村庄到医院最近)或能使所有的村庄到达医院的距离之和达到最小。 我的思路是: A. 首先是,随机生成了村庄的数量,定义结构变量,通过调用GreateUDN函数给顶点表赋值,随机生成村庄之间的路径长度并存... 阅读详情

思路

不妨考虑使用最短路径(动态规划 +++ 递推)解决这个问题。

首先,设定第 111 个楼的位置作为坐标原点,第 iii 个楼的位置表示为 did_idi​。通过逻辑推理,我们可以得出,如果在 di−1d_{i-1}di−1​ 和 did_idi​ 中选择一个地点建立学校,那么最优的学校位置一定是这两个端点中的一个。具体地:

  • 当前 i−1i - 1i−1 个大楼的总学生数大于第 iii 到 nnn 个大楼的总学生数时,选择 did_idi​ 处建学校;
  • 如果小于,则选择 di−1d_{i - 1}di−1​ 处建学校;
  • 如果等于,两个点都可以作为学校的位置。
利用平面直角坐标系的知识

预处理一个二维数组 gi,jg_{i,j}gi,j​,表示只考虑第 iii 到第 jjj 个楼的学生时,放置学校的最优位置。

再定义一个动态规划数组 fi,kf_{i,k}fi,k​,表示在前 iii 个楼范围内建立 kkk 个学校时,可达到的最小总距离和。

  • 当 k≥ik \geq ik≥i 时,fi,k=0f_{i,k} = 0fi,k​=0(即,学校数量足够多,可以每个楼都建一个学校,没有距离成本);
  • 当 k=1k = 1k=1 时,fi,k=g1,if_{i,k} = g_{1,i}fi,k​=g1,i​(即,只建一个学校时,选择范围内最优位置);
  • 在其他情况下,考虑最后一个学校覆盖的楼房范围。如果是建在 dld_ldl​ 到 did_idi​ 之间,则最小总距离为 fl−1,k−1+gl,if_{l-1, k-1} + g_{l, i}fl−1,k−1​+gl,i​。

因此,动态规划的转移方程为:

fi,k=min⁡l=1i(fl−1,k−1+gl,i) f_{i,k} = \min_{l = 1}^{i} \left( f_{l-1, k-1} + g_{l, i} \right) fi,k​=l=1mini​(fl−1,k−1​+gl,i​)

最终结果即为 fn,Kf_{n, K}fn,K​,表示在所有楼中建立 KKK 个学校时的最小总距离和。


通过这种方式,我们可以系统地将问题分解为可管理的子问题,通过计算每个子问题的最优解并将这些解逐步合并,最终得到整个问题的最优解。

代码(有注释):

#include <iostream>
#include <cstring>

using namespace std;

const int N = 110; // 定义常量N作为楼房数量和学校数量的最大值
int n, K;          // n代表楼房的数量,K代表要建立的学校的数量
int dis[N];        // dis数组存储从第一个楼房到当前楼房的总距离
int g[N][N], f[N][N], w[N]; // g数组存放子问题最优情况下的最小总距离和
                            // f数组用于动态规划,记录考虑前i座楼房建j所学校的最小总距离和
                            // w数组存放每个楼房人数的前缀和

int main() {
  // 读入楼房数量和需要建立的学校数量
  scanf("%d%d", &n, &K);
  // 初始化第0座楼房的累计人数为0
  w[0] = 0;
  // 循环读入每座楼房的人数,并计算累计人数
  for (int i = 1; i <= n; i++) {
    int x;
    scanf("%d", &x);
    w[i] = w[i - 1] + x;
  }
  // 初始化第1座楼房的累计距离为0
  dis[1] = 0;
  // 循环读入相邻楼房之间的距离,并计算每座楼房的累计距离
  for (int i = 2; i <= n; i++) {
    int x;
    scanf("%d", &x);
    dis[i] = dis[i - 1] + x;
  }

  // 计算g数组中每个子问题的最优解
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= i; j++) {
      // 确定放置学校的最优位置
      int k;
      for (k = j; k <= i; k++)
        if (w[k] - w[j - 1] >= w[i] - w[k]) break;
      k = min(k, i);

      // 计算j到i所有楼房到学校k的距离和
      for (int l = j; l <= i; l++)
        g[j][i] += abs(dis[k] - dis[l]) * (w[l] - w[l - 1]);
    }

  // 初始化动态规划数组f,填充一个较大的数(表示距离无穷大)
  memset(f, 0x3f, sizeof f);
  // 动态规划计算至最多n座楼房,建立至多K座学校的最小总距离和
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= K; j++) {
      if (j >= i) f[i][j] = 0; // 学校数量不少于总楼房数,每座楼配一个学校,距离和为0
      else if (j == 1) f[i][j] = g[1][i]; // 只建一个学校的情况,距离和直接取g数组对应值
      else {
        // 枚举可能的学校位置,通过子问题的最优解更新当前问题的最小距离和
        for (int l = 1; l <= i; l++)
          f[i][j] = min(f[i][j], f[l - 1][j - 1] + g[l][i]);
      }
    }

  // 输出从1到n座楼房,建立K所学校的最小总距离和
  printf("%d\n", f[n][K]);
}
数据结构:用Floyd算法求医院选址问题(附注释) 医院选址问题 [问题描述] 有一个乡镇,共有n个村庄,现在要建立一家医院, 那么医院应该选址在哪个村庄合适呢?设计算法,满足如下选址要求:使得所有村庄到达医院都最近。 [基本要求] (1) 随机生成一个有n个村庄和村庄间的路径及路径长度,并输出; (2) 显示出各村庄到医院的路径和路径长度。 算法思想: 1、将图中各顶点代表村庄,顶点之间的连线代表村庄之间的路径。由此交通图就转化成了有限顶点和有限条边组成的无向图,图中顶点之间的关系用权值表示。 2、求最佳选址通常有两种思路:一是求最小路径总和最小,这种情 阅读详情

相关推荐

医院选址问题(数据结构)大作业.pdf

计算机科学与技术专业数据结构大作业 1 一、 实验内容概述 n 个村庄之间的交通图用有向加权图表示,图中的有向边<vi ,vj>表示第 i 个村庄和第 j 个村庄之间有道路, 边上的权表示这条道路的长度。 现在要从这 n 个村庄中选择一个村庄建 一所医院,问这所医院应建在哪个村庄,才能使离医院最远的村庄到医院最近。 图 1 医院选址加权有向图 测试数据:针对图 1,输入以下数据: 输入顶点数: 5 输入顶点对和弧的权值: 1 2 1 2 3 2 3 4 2 3 5 4 4 2 1 4 3 3 5 4 5 0 0 0 计算机科学与技术专业数据结构大作业 2 二、 实验目的概述 "数据结构"是计算机科学与技术专业一门十分重要的专业技术基础课, 计算机科学各领 域及有关的应用软件都要使用到各种数据结构。在我国, "数据结构与算法"已经作为理工科 非计算机专业必修的信息技术基础课程之一。 世界上许多科技人员对学习、 研究数据结构和 算法都非常重视, 对于从是计算机科学及其应用的科技工作者来说, 数据结构与算法更是必 须透彻的掌握的重要基础。 学习数据结构与算法的最终目的是解决实际的应用问题,特

基于数据结构知识解决学校超市选址问题

由于上述,最优权值在数组中的位置对应的单位就是最优选址,我们假设它在数组中的位置是i,那么单位名称数组中的第i个字符串就是最优选址的名称。距离矩阵中第i列元素是各个单位到选址超市的距离,距离矩阵中第i列各元素与频度数组中与该元素所在行的下标相同的值相乘就是相应单位到选址超市的权数。我们将各个单位到选址地的距离与该单位人员去超市频度的乘积作为单位的权数,再把各单位总权数相加所得的和作为该选址的一个优、劣度量标准。需要传入的参数是:指向单位间的距离矩阵的指针、指向单位人员去超市的频度的指针、单位数量。

m0_54570435的博客 1732

window下安装并使用nvm(含卸载node、卸载nvm、全局安装npm)

文章目录一、卸载node二、安装nvm三、配置路径和下载源四、使用nvm安装node五、nvm常用命令六、卸载nvm七、遇到的问题 nvm 全名 node.js version management,顾名思义是一个nodejs的版本管理工具。通过它可以安装和切换不同版本的nodejs。 一、卸载node 如果你已经安装了node,那么你需要先卸载node,如果你没有安装那直接跳过这一步到下一步。 打开控制面板 -> 打开程序和功能 -> 右上角搜索输入node -> 右键卸载 为了确保彻底

HuangsTing的博客 41万+

【洛谷】P2803 学校选址II

在一条大路一旁有许多栋楼,每栋楼里有许多小学生(哈哈哈一波小学生来袭!所以唯恐世界不乱的牛A打算在路上(汽车什么的都不敢来这个小学生云集的地方咯,所以不用担心安全问题)任选几点(可以和楼重合,当然也可以不重合)建立小学,且使所有小学生上学走的路程之和最短。剩余情况,可以按最右边的那个学校建在什么地方来分类,如果是建在。个学校的情况下,最小的总距离和是多少。的楼的学生的时候,最优的放置学校的位置。个大楼的总学生数的时候,显然要选。,即只建一个学校,则根据定义,个整数,表示每栋楼的学生数(......

数学、算法爱好者的博客 593

嵌入式开发避坑指南:手把手教你用STM32CubeMX配置W9825G6KH SDRAM(含时序参数详解)

本文详细介绍了如何使用STM32CubeMX配置W9825G6KH SDRAM,包括硬件连接检查、CubeMX初始化步骤、时序参数优化及稳定性问题排查。通过实测波形分析和案例分享,帮助开发者避免常见配置错误,提升嵌入式系统性能与稳定性。

weixin_42542669的博客 197

FFmpeg + OBS 低延迟直播串流实战:从H264裸流到RTP组播的完整配置

本文详细介绍了如何利用FFmpeg将H264裸流转码为RTP协议,并通过组播技术实现与OBS客户端的超低延迟直播串流。文章深入剖析了FFmpeg关键参数调优、SDP文件生成与配置,以及OBS客户端的无缝拉流方法,为需要毫秒级实时交互的场景提供了一套去中心化、高效稳定的完整解决方案。

fanta的博客 830

【DG特长生2018 T3】【SSL 2887】【luogu P2803】建学校问题 / 学校选址 II

有 n 个城市链状排着,编号相邻的连接,然后有边权和点权。 你可以选 k 个点,然后对于每个点,它会找距离它最近的你选的点,然后它的费用就是它的点权乘到你选的点的距离。 然后你要让总费用最小。

欢迎您的光顾awa 297

Python学习24:中国古代数学问题——物不知数(Python123)

意思是说有一些物品,不知道有多少个,3个3个数的话,还多出2个;5个5个数则多出3个;7个7个数也会多出2个。题目为‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬‬:今有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二,问物几何?现假设物品总数不超过n (n

weixin_60530224的博客 2万+

树形结构在医院选址问题中的算法优化与应用

图论中的树结构是一种重要的数据结构,具有无环和唯一路径的特性,广泛应用于路径优化问题。通过DFS/BFS遍历和LCA算法,可以高效计算树节点间距离。动态规划思想能进一步优化计算过程,将时间复杂度从O(n²)降至O(n)。这种技术在公共服务设施选址、物流中心规划等场景有重要价值。以医院选址问题为例,需要最小化人口加权的总距离代价,这涉及到树形DP和二进制提升等经典算法优化。实际应用中还需考虑加权边、多设施选址等扩展场景,体现了算法设计与工程实践的紧密结合。

weixin_32956805的博客 107

Transformer代码(Pytorch实现和详解)!!!

这个是第一版,有些代码如果不对,欢迎在评论指正,后续会慢慢改,我也是刚接触transformer,若有些地方理解不对还请指正。

xml的博客 5613

IIC软件协议及硬件知识汇总

IIC软件协议及硬件相关知识,真的是非常齐全了!

记得诚 1万+

数据结构案例经验分享--医院选址问题(C语言实现)

数据结构实验案例分享--医院选址问题问题描述 问题描述

sy_han的博客 1万+

【深度学习】什么是自回归模型?

自回归模型是一种重要的时间序列模型,通过利用过去的值来预测当前或未来的值。它在统计学、经济学、自然语言处理等领域有广泛的应用。自回归模型的简单性和可解释性使其成为许多应用的首选,但在更复杂的情况下,可能需要结合其他模型如移动平均模型(MA模型)或混合模型(如ARIMA)来更好地捕捉时间序列中的模式。扩散模型(Diffusion Model)和自回归模型(Autoregressive Model)是两种不同的生成模型,各自有独特的特点和应用场景。

q742971636的博客 1672

深挖C++:类和对象(中)

(先进后出)

xys_678的博客 249

2025.05.29【Network】多组学分析:网络互作图绘制

本文介绍了使用R语言进行网络图绘制的方法与技巧。重点讲解了三个核心R包的使用:igraph用于网络图数据准备与基础绘制,ggraph基于图形语法实现高级可视化,networkD3则为网络图添加交互功能。文章涵盖了从基本概念、包安装、创建网络图对象,到自定义样式布局、添加交互性等完整流程,并提供了度分布、聚类系数等网络分析指标的计算方法。通过清晰的代码示例,帮助读者掌握生物信息学数据可视化的关键技能,为复杂数据的直观展示和分析提供实用工具。

227

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

ThunderKittens 深度解析:一个不基于 MLIR 的 C++ 模板 GPU DSL

Triton 是"让更多人能写 GPU kernel",ThunderKittens 是"让会写的人写得更爽"。前者用 MLIR 换易用性,后者用 C++ 模板换可控性。它们不是替代关系,而是覆盖了 GPU 编程光谱的两端。ThunderKittens 的出现,本质上是对"GPU DSL 必须基于 MLIR"这一默认假设的挑战。编译期类型系统本身就可以是一个强大的 DSL 基础设施,不需要中间 IR,不需要黑盒 pass,也能实现 tile 级抽象和零运行时开销。

Maxwell_Newton的博客 345

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

C++移动构造函数详解

移动构造函数是C++11引入的一种特殊构造函数,用于从临时对象(右值)"窃取"资源来初始化新对象,而不是进行昂贵的深拷贝。char* data;public:// 移动构造函数:参数是右值引用 &&// 关键:把源对象的资源置空。

拒绝AI文,努力在AI时代写出感动人心的好文章 393

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

跟我学c++中级篇—类型定义的方式

本文系统阐述了编程中类型定义的重要性及c++中的实现方式。重点对比了宏定义、typedef与modern using三种机制,指出using在可读性、灵活性和模板支持上的优势,推荐优先使用。同时提醒开发者注意别名滥用、类型歧义、错误信息冗长等问题,强调统一规范与合理设计。最终结论:在现代c++开发中,应以using为主,兼顾简洁性与可维护性,避免陷入命名混乱与编译困境。

fpcc的专栏 86

C++ 函数模版

模板参数:● template ,T 就是类型占位符,名字可以自定义,习惯用T● 占位符可以在函数返回值、形参、函数内部当作类型使用使用要点模板代码一般写在头文件:编译器需要看到完整模板源码,才能在每个编译单元完成实例化全局函数、类内成员函数都可以写成模板实例化发生在编译阶段,不是运行时隐式实例化:调用时编译器自动推导实参类型,生成对应版本函数。

2501_94041724的博客 306

C++ 运行时多态与虚函数机制全面剖析【面试重点】

构成C++ 运行时多态必须是基类的指针或者引用调用虚函数。被调用的函数必须是虚函数,并且派生类必须对该虚函数完成重写/覆盖(Override)。只有基类的指针或引用才能既指向基类对象,又指向派生类对象(切片机制);而只有完成了虚函数重写,派生类与基类才具备不同的函数行为,达到“指向谁就调用谁”的效果。在类成员函数的前面加上virtual关键字修饰,该成员函数就成为了虚函数。public:// 成员函数前加 virtual 修饰,声明为虚函数。

Fuyo_0209的博客 447

#SQLite 数据库笔记一:(概念 / 终端指令 / SQL 语句 / C 编程 / 回调函数)

数据库 = 数据的仓库,假设数据是海量。能力说明存储数据持久化保存,程序退出数据还在统计数据、分组、排序数据管理增、删、改、查(CRUD)嵌入式设备上也会用数据库(单片机网关、路由器、工业 HMI 都常见),因为 sqlite 体积小、无需服务进程、单文件即可。数据库 = 库 > 表 > 记录(行) > 字段(列)sqlite3 = 开源、C 写的、单文件、免安装、最多 2T 的嵌入式关系型数据库。

lwq20051110的博客 221

【C++ 基础入门】C++继承(下):问题、底层原理与组合

C++继承(菱形继承的问题、虚继承原理、继承与组合、构造顺序)

2601_96587588的博客 797

蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级 备考:莫队算法离线区间查询详解

备赛进行时:第十八届蓝桥杯软件赛报名已于 2026-10-08 10:00 开启、12-18 14:00 截止,省赛定在 2027-04-10(C/C++·Python 程序设计 9:00–13:00);中国电子学会 2026 年 12 月软件编程(C/C++ 一级至十级、Python 一级至六级)考级报名 9/23–12/2 16:00、统考 12-12;全国青少年信息素养大赛 2026—2027 赛季算法应用主题赛也已进入复盘练兵窗口。

IT_Scratch的博客 160

825 mW 顶上 212 °C:ASM491S 的 105 °C/W、250 mA 短路电流与热关断

25 °C 环境里结温 34.1 °C,125 °C 环境里结温 134.1 °C——后者已经离 150 °C 只有 16 °C 了,但还在范围内。换个角度看同一件事:从 25 °C 和从 125 °C 起算,温升都是 86.6 °C,但一个到 111.6 °C(还在范围内),一个到 211.6 °C(远远超限)。这个算例里 20 °C/W 是我假设的,实际值取决于机壳材料、密封程度、有没有风扇,跨度可以从 5 °C/W 到 50 °C/W 以上。外面 50 °C 的机箱,盒内就是 63.9 °C。

ANSILIC的博客 373

《C++ 项目:手写大模型接入 SDK》Gemini接口设计(上):初始化、全量响应实现和测试

本文系统完成了Gemini模型通过OpenAI兼容API的接入开发,基于Apifox验证接口规范,设计并实现GeminiProvider类,涵盖初始化、状态检测、全量响应等核心功能。重点处理了代理配置强制校验、Bearer鉴权、JSON序列化与响应解析等工程细节,并通过GTest与CMake完成单元测试,验证链路可用性。项目遵循策略模式,保持与DeepSeek、ChatGPT等模型的统一抽象接口,显著提升SDK可扩展性。

2501_91275995的博客 395

【容斥原理计数】题解:P9489 ZHY的表示法_容斥原理_计数问题_前缀和问题转化_算法竞赛C++

给定 $ n $ 个正整数,求区间 $[l,r]$ 中有多少正整数 $ x $ 可表示为 $ \sum \lfloor \frac{y}{x_i} \rfloor $。通过二分确定最大 $ y $,转化为求 $ 1 \sim H $ 中是某些 $ x_i $ 倍数的数的个数,利用容斥原理与 DFS 枚举子集计算,结合 LCM 预判剪枝及去重优化,时间复杂度 $ O(2^n \log V) $,可高效处理 $ r \le 10^9 $ 的数据。

YLCHUP的博客 104
上一篇: Claude3 正式发布,支持多模态(附注册使用教程)
下一篇: 如何搭建SearXNG搜索引擎
Chat_lsm2024
博客等级 码龄7年 903粉丝 79原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值