题目描述(手头没书,不知道有没有记错):有v个在一条直线上的村庄,要在其中的p个村庄上修建邮局。每个村庄将会选择离其最近的村庄收发邮件。现在要选择这p个邮局的修建地址,使得这v个村庄到邮局的总路程尽可能少。
输入:首先是两个正整数v,p,表示村庄个数与邮局个数。
然后是v个不小于零的整数,表示v个村庄的坐标。
输出:p从小到大个用空格分开的整数,表示p个邮局的坐标。
这个题目用简单的重举法显然是行不通的,那样时间复杂度将达到阶乘级别。
我用的是动态规划,时间复杂度为O(n*n*(n+p)).不知道有没有更好的算法。
注意:这个题目的解实际上不唯一,比如v=2,p=1的情形,邮局修在村庄1与村庄2是一样的。[/color]
/**
* &#Postoffice.java
* 算法描述:
* 记m(i,j)为前i个村庄设置j个邮局时最小的总路程,
* s(i,j)为从村庄i到j中(包括i,j)中设置一个村庄时需要的最小路程,则有:
* m(i,j) =min{ m(k,j-1)+s(k,i-1) : j-1<=k<=i-1}
* 则状态总数为 O(n*(p+n)),转移代价为O(n),故总体时间复杂度为O(n*n*(n+p))
* @author Eastsun
* @version 2.0 2008/8/27
*/
package eastsun.algorithm;
import java.util.*;
public class Postoffice {
private Postoffice() {
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int v = s.nextInt();
int p = s.nextInt();
int[] villages = new int[v];
for (int index = 0; index < v; index++) {
villages[index] = s.nextInt();
}
for (int post : solve(villages, p)) {
System.out.println(post + " ");
}
}
/**
* 求解
* @param villages 村庄坐标
* @param p 邮局个数
* @return postoffices 按升序排列的邮局坐标
*/
public static int[] solve(int[] villages, int p) {
Arrays.sort(villages);
int v = villages.length;
//对于p<=2时,特殊处理
if (p <= 2) {
return solveX(villages, p);
}
//simple[i][j] 表示从村庄i到j(包括i,j)中放置一个邮局时这些村庄要走的路程
int[][] simple = new int[v][v];
for (int i = 0; i < v; i++) {
for (int j = i; j < v; j++) {
//此时,将邮局修在中间那个村庄可以得到最小路程
int pos = (i + j) / 2;
for (int k = i; k <= j; k++) {
simple[i][j] += k <= pos ? villages[pos] - villages[k] : villages[k] - villages[pos];
}
}
}
//min[i][j] 表示在villages[0...i-1]中修建j个邮局时最小的路程
int[][] min = new int[v + 1][p + 1];
//trace[i][j] 表示这j个邮局中最后一个邮局影响村庄的起始位置
int[][] trace = new int[v + 1][p + 1];
for (int i = 1; i <= v; i++) {
min[i][1] = simple[0][i - 1];
}
for (int j = 2; j <= p; j++) {
for (int i = j; i <= v; i++) {
min[i][j] = Integer.MAX_VALUE;
for (int k = j - 1; k <= i - 1; k++) {
if (min[i][j] > min[k][j - 1] + simple[k][i - 1]) {
min[i][j] = min[k][j - 1] + simple[k][i - 1];
trace[i][j] = k;
}
}
}
}
int[] postoffices = new int[p];
int end = v - 1;
for (int index = p - 1; index >= 0; index--) {
int begin = trace[end + 1][index + 1];
postoffices[index] = villages[(begin + end) / 2];
end = begin - 1;
}
return postoffices;
}
/**
* 对邮局个数为1或2时的处理
* 此时对应的时间复杂度为O(1) 与O(n*n)
*/
private static int[] solveX(int[] villages, int p) {
int v = villages.length;
if (p == 1) {
return new int[]{villages[(v - 1) / 2]};
} else {
int pos = 0;
int min = Integer.MAX_VALUE;
for (int index = 0; index < v - 1; index++) {
int p1 = index / 2;
int p2 = (index + v) / 2;
int tmp = 0;
for (int k = 0; k < v; k++) {
if (k <= index) {
tmp += k <= p1 ? villages[p1] - villages[k] : villages[k] - villages[p1];
} else {
tmp += k <= p2 ? villages[p2] - villages[k] : villages[k] - villages[p2];
}
}
if (tmp < min) {
min = tmp;
pos = index;
}
}
return new int[]{villages[pos / 2], villages[(pos + v) / 2]};
}
}
}
分享到:
- 2007-08-19 19:55
- 浏览 3309
- 评论(8)
- 论坛回复 / 浏览 (7 / 4085)
- 查看更多
相关推荐
**第八章 指针** 指针是C语言的一大特色,它允许直接操作内存地址。本章讨论了指针变量的定义和使用,以及指针的运算,包括间接访问、赋值和加减运算。指针与数组、函数的结合使用,如指向数组的指针(行指针)和...
【第8章 指针】是C语言的一大特色,指针变量用于存储内存地址,可以直接访问和修改变量的值。指针的基本运算包括间接访问、赋值和算术运算。指向数组和结构体的指针使得我们能够灵活地操作数据结构。函数参数也可以...
修炼成Javascript中级程序员必知必会_资源分享
内容概要:本文详细介绍了如何使用MATLAB的深度学习工具箱,在果树病虫害识别任务中从数据准备、模型设计、训练优化到最后的模型评估与应用全流程的具体实施步骤和技术要点。涵盖了MATLAB深度学习工具箱的基本概念及其提供的多种功能组件,如卷积神经网络(CNN)的应用实例。此外,文中还具体讲述了数据集的收集与预处理方法、不同类型的深度学习模型搭建、训练过程中的超参数设定及其优化手段,并提供了病虫害识别的实际案例。最后展望了深度学习技术在未来农业领域的潜在影响力和发展前景。 适合人群:对深度学习及农业应用感兴趣的科研人员、高校师生和相关从业者。 使用场景及目标:①希望掌握MATLAB环境下构建深度学习模型的方法和技术细节;②从事果树病虫害管理研究或实践,寻找高效的自动化解决方案。 阅读建议:在阅读本文之前,建议读者熟悉基本的MATLAB编程环境及初步了解机器学习的相关概念。针对文中涉及的理论和技术难点,可以通过官方文档或其他教程进行补充学习。同时,建议动手实践每一个关键点的内容,在实践中加深理解和掌握技能。
nodejs010-nodejs-block-stream-0.0.7-1.el6.centos.alt.noarch.rpm
机械模型与技术交底书的融合:创新点详解与解析,机械模型加技术交底书,有创新点 ,机械模型; 技术交底书; 创新点,创新机械模型与技术交底书详解
免费JAVA毕业设计 2024成品源码+论文+数据库+启动教程 启动教程:https://www.bilibili.com/video/BV1SzbFe7EGZ 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx
免费JAVA毕业设计 2024成品源码+论文+数据库+启动教程 启动教程:https://www.bilibili.com/video/BV1SzbFe7EGZ 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx
nodejs010-nodejs-cmd-shim-1.1.0-4.1.el6.centos.alt.noarch.rpm
西门子四轴卧加后处理系统:828D至840D兼容,四轴联动高效加工解决方案,支持图档处理及试看程序。,西门子四轴卧加后处理,支持828D~840D系统,支持四轴联动,可制制,看清楚联系,可提供图档处理试看程序 ,核心关键词:西门子四轴卧加后处理; 828D~840D系统支持; 四轴联动; 制程; 联系; 图档处理试看程序。,西门子四轴卧加后处理程序,支持多种系统与四轴联动
基于黏菌优化算法(SMA)的改进与复现——融合EO算法更新策略的ESMA项目报告,黏菌优化算法(SMA)复现(融合EO算法改进更新策略)——ESMA。 复现内容包括:改进算法实现、23个基准测试函数、多次实验运行并计算均值标准差等统计量、与SMA对比等。 程序基本上每一步都有注释,非常易懂,代码质量极高,便于新手学习和理解。 ,SMA复现;EO算法改进;算法实现;基准测试函数;实验运行;统计量;SMA对比;程序注释;代码质量;学习理解。,标题:ESMA算法复现:黏菌优化与EO算法融合改进的实证研究
基于MATLAB的Stewart平台并联机器人仿真技术研究与实现:Simscape环境下的虚拟模拟分析与应用,MATLAB并联机器人Stewart平台仿真simscape ,MATLAB; 并联机器人; Stewart平台; 仿真; Simscape; 关键技术。,MATLAB中Stewart平台并联机器人Simscape仿真
Grad-CAM可视化医学3D影像
探索comsol泰勒锥:电流体动力学的微观世界之旅,comsol泰勒锥、电流体动力学 ,comsol泰勒锥; 电流体动力学; 锥形结构; 电场影响,COMSOL泰勒锥与电流体动力学研究
免费JAVA毕业设计 2024成品源码+论文+数据库+启动教程 启动教程:https://www.bilibili.com/video/BV1SzbFe7EGZ 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx
PFC6.03D模型动态压缩模拟与SHPB霍普金森压杆系统理论及实验数据处理技术解析,PFC6.03D模型,动态压缩模拟,还包括: SHPB霍普金森压杆系统理论知识介绍,二波法和三波法处理实验数据,提出三波波形,计算动态压缩强度等 ,PFC模型; 动态压缩模拟; SHPB霍普金森压杆系统; 理论介绍; 二波法处理; 三波法处理; 三波波形; 动态压缩强度。,"PFC模型下的动态压缩模拟及SHPB理论实践研究"
ProASCI 开发板原理图,适用于A3P3000
免费JAVA毕业设计 2024成品源码+论文+录屏+启动教程 启动教程:https://www.bilibili.com/video/BV1SzbFe7EGZ 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx
1、文件内容:pykde4-devel-4.10.5-6.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/pykde4-devel-4.10.5-6.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、安装指导:私信博主,全程指导安装
基于Comsol模拟的三层顶板随机裂隙浆液扩散模型:考虑重力影响的瞬态扩散规律分析,Comsol模拟,考虑三层顶板包含随机裂隙的浆液扩散模型,考虑浆液重力的影响,模型采用的DFN插件建立随机裂隙,采用达西定律模块中的储水模型为控制方程,分析不同注浆压力条件下的浆液扩散规律,建立瞬态模型 ,Comsol模拟; 随机裂隙浆液扩散模型; 浆液重力影响; DFN插件; 达西定律模块储水模型; 注浆压力条件; 浆液扩散规律; 瞬态模型,Comsol浆液扩散模型:随机裂隙下考虑重力的瞬态扩散分析