leetcode1066 校园自行车分配II

题目描述

在由 2D 网格表示的校园里有 n 位工人(worker)和 m 辆自行车(bike),n <= m。所有工人和自行车的位置都用网格上的 2D 坐标表示。

我们为每一位工人分配一辆专属自行车,使每个工人与其分配到的自行车之间的曼哈顿距离最小化。

p1 和 p2 之间的曼哈顿距离为 Manhattan(p1, p2) = |p1.x - p2.x| + |p1.y - p2.y|。

返回每个工人与分配到的自行车之间的曼哈顿距离的最小可能总和。

示例1:

输入:workers = [[0,0],[2,1]], bikes = [[1,2],[3,3]]
输出:6
解释:
自行车 0 分配给工人 0,自行车 1 分配给工人 1 。分配得到的曼哈顿距离都是 3, 所以输出为 6 。

示例2:

输入:workers = [[0,0],[1,1],[2,0]], bikes = [[1,0],[2,2],[2,1]]
输出:4
解释:
先将自行车 0 分配给工人 0,再将自行车 1 分配给工人 1(或工人 2),自行车 2 给工人 2(或工人 1)。如此分配使得曼哈顿距离的总和为 4。

提示:

1. 0 <= workers[i][0], workers[i][1], bikes[i][0], bikes[i][1] < 1000
2. 所有工人和自行车的位置都不相同。
3. 1 <= workers.length <= bikes.length <= 10

解题思路

暴力搜索

很自然我们想到可以使用两个bitmap: workerBitmap 和 bikeBitmap 来标识哪些工人和自行车已经匹配,下一步是从两个bitmap中选取没有被占用的位置进行匹配,暴力搜索如下,在运行到11的用例的时候判断超时失败。

int getBikeDistance(int *worker, int *bike)
{return abs(worker[0] - bike[0]) + abs(worker[1] - bike[1]);
}
​
int helper(int** workers, int* workersBitmap, int workersSize, int** bikes, int* bikesBitmap, int bikesSize)
{int assignWorkerSize = 0;for (int i = 0; i < workersSize; i++) {if (workersBitmap[i]) {assignWorkerSize ++;}}
​if (assignWorkerSize == workersSize) {return 0;}
​int minDist = INT_MAX;for (int i = 0; i < workersSize; i++) {if (workersBitmap[i] == 1) {continue;}
​workersBitmap[i] = 1;for (int j = 0; j < bikesSize; j++) {if (bikesBitmap[j] == 1) {continue;}
​bikesBitmap[j] = 1;
​int dist = getBikeDistance(workers[i], bikes[j]);dist += helper(workers, workersBitmap, workersSize, bikes, bikesBitmap, bikesSize);
​minDist = dist > minDist ? minDist : dist;bikesBitmap[j] = 0;}workersBitmap[i] = 0;}
​return minDist;
}
​
int assignBikes(int** workers, int workersSize, int* workersColSize, int** bikes, int bikesSize, int* bikesColSize)
{int workersBitmap[workersSize];int bikesBitmap[bikesSize];
​memset(workersBitmap, 0, sizeof(workersBitmap));memset(bikesBitmap, 0, sizeof(bikesBitmap));
​return helper(workers, workersBitmap, workersSize, bikes, bikesBitmap, bikesSize);
}

BackTracing+位压缩

在暴力解法中,我们每一次从worker集合中随机取一个worker和bike集合中的一个进行匹配,最后worker的bitmap都是全1的,导致我们随机选取worker的过程中会有大量的重复操作(匹配结果都相同)。

我们考虑按序使用每一个worker去和bike集中的一个进行匹配,继续保留bikeBitmap。所以如果第 i 个worker匹配到了第 j 个bike之后,实际上前i个workerBitmap中的元素已经全部置1,匹配第i + 1的时候,我们可以从bikeBitmap中挑选0的bike进行匹配。最后的最优解就是第i个元素匹配上的bike的曼哈顿距离加上任意选择一个后从第 i + 1个worker开始和剩余bike的和的最小值。

观察到题目限制,工人和单车最多只有10个,所以我们可以将bike的状态压缩到一个INT32的数字中,然后从前往后回溯。提交显示AC 992ms。

int getBikeDistance(int *worker, int *bike)
{return abs(worker[0] - bike[0]) + abs(worker[1] - bike[1]);
}int helper(int** workers, int workerIndex, int workersSize, int** bikes, int bikeState, int bikesSize)
{if (workerIndex == workersSize) {return 0;}int minDist = INT_MAX;for (int bikeIndex = 0; bikeIndex < bikesSize; bikeIndex++) {if ((bikeState & (1 << bikeIndex)) != 0) {continue;}int dist = getBikeDistance(workers[workerIndex], bikes[bikeIndex]) + helper(workers, workerIndex + 1, workersSize, bikes, bikeState | (1 << bikeIndex), bikesSize);minDist = dist > minDist ? minDist : dist;}return minDist;
}int assignBikes(int** workers, int workersSize, int* workersColSize, int** bikes, int bikesSize, int* bikesColSize)
{return helper(workers, 0, workersSize, bikes, 0, bikesSize);
}

BackTracking+位压缩+记忆化搜索去重

在上面的方法中,我们已经通过回溯方法通过了此问题。我们画出问题决策树,可以看到选择不同的bike之间存在大量的重复。

我们可以将节点看作是问题的最优解,使用一个Memo数组记忆化去重。AC通过时间4ms。

#define MAX_BIKE_STATE 1024
int g_workerBikeDistance[MAX_BIKE_STATE];
​
int workerBikeDistance(int *worker, int *bike)
{return abs(worker[0] - bike[0]) + abs(worker[1] - bike[1]);
}
​
int helper(int** workers, int workerIndex, int workersSize, int** bikes, int bikeState, int bikesSize)
{if (workerIndex == workersSize) {return 0;}
​int minDist = INT_MAX;for (int bikeIndex = 0; bikeIndex < bikesSize; bikeIndex++) {if ((bikeState & (1 << bikeIndex)) != 0) {continue;}
​int dist = workerBikeDistance(workers[workerIndex], bikes[bikeIndex]);if (g_workerBikeDistance[bikeState | (1 << bikeIndex)] == -1) {dist += helper(workers, workerIndex + 1, workersSize, bikes, bikeState | (1 << bikeIndex), bikesSize);} else {dist += g_workerBikeDistance[bikeState | (1 << bikeIndex)];}minDist = minDist > dist ? dist : minDist;}g_workerBikeDistance[bikeState] = minDist;return minDist;
}
​
int assignBikes(int** workers, int workersSize, int* workersColSize, int** bikes, int bikesSize, int* bikesColSize)
{memset(g_workerBikeDistance, -1, sizeof(g_workerBikeDistance));
​return helper(workers, 0, workersSize, bikes, 0, bikesSize);
}

leetcode1066 校园自行车分配II相关推荐

  1. LeetCode 1066. 校园自行车分配 II(状态压缩DP)

    文章目录 1. 题目 2. 解题 2.1 回溯超时 2.2 状态压缩DP 1. 题目 在由 2D 网格表示的校园里有 n 位工人(worker)和 m 辆自行车(bike),n <= m.所有工 ...

  2. LeetCode 1057. 校园自行车分配(map有序+贪心)

    文章目录 1. 题目 2. 解题 1. 题目 在由 2D 网格表示的校园里有 n 位工人(worker)和 m 辆自行车(bike),n <= m.所有工人和自行车的位置都用网格上的 2D 坐标 ...

  3. LeetCode1066_校园自行车分配II_动态规划_位运算_Java

    B站视频地址:https://www.bilibili.com/video/BV18G4y1a7d9/?vd_source=a0bea6f5def58dc5711647a825ed97b6 代码 cl ...

  4. 基于jsp+mysql的JSP校园自行车租赁网站平台管理系统

    运行环境: 最好是java jdk 1.8,我们在这个平台上运行的.其他版本理论上也可以. IDE环境: Eclipse,Myeclipse,IDEA都可以 tomcat环境: Tomcat 7.x, ...

  5. javaweb校园自行车租赁系统

    校园自行车租赁系统主要是采用jsp的mvc技术.mysql数据库.Tomcat服务器作为开发平台,系统采用B/S结构进行开发.目标是实现一个以租赁为中心的校园自行车租赁系统,构建用户信息与账号,账号与 ...

  6. 基于java+springboot+mybatis+vue+elementui的校园自行车租赁系统

    项目介绍 许多先进国家早已致力于发展自行车替代高能耗.高排放的交通工具.然而传统落后的自行车租赁管理模式仍然在很大程度上制约了推行公共自行车租赁普及化和现代化的发展,成为更深层次的"软环境& ...

  7. 基于java校园自行车租赁系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署

    基于java校园自行车租赁系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署 基于java校园自行车租赁系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署 本源码技术栈 ...

  8. php校园寝室分配查询系统 毕业设计源码032027

    php校园寝室分配查询系统 摘 要 网络的广泛应用给生活带来了十分的便利.所以把校园寝室分配查询与现在网络相结合,利用PHP技术建设校园寝室分配查询系统,实现学生寝室的信息化.则对于进一步提高校园寝室 ...

  9. php校园寝室分配查询系统 毕业设计-源码032027

    php校园寝室分配查询系统 摘 要 网络的广泛应用给生活带来了十分的便利.所以把校园寝室分配查询与现在网络相结合,利用PHP技术建设校园寝室分配查询系统,实现学生寝室的信息化.则对于进一步提高校园寝室 ...

最新文章

  1. FLUSH TABLES WITH READ LOCK
  2. python中文版编译器下载-python编译器
  3. react 原生html 插件,纯原生JS的瀑布流插件Macy.js,前端必备插件
  4. 使用SSL和Spring Security保护Tomcat应用程序的安全
  5. 对象交互 空调与摇控器 0107
  6. 【376天】每日项目总结系列113(2018.02.16)
  7. Singular Value Decomposition(SVD)--奇异值分解【转】
  8. HTTP状态码大全(常见 HTTP Status Code 含义查询)
  9. 简要介绍电源效率测试
  10. android手机壁纸尺寸,安卓手机壁纸尺寸选择攻略:屏幕分辨率≠壁纸分辨率
  11. ppt太大怎么变小,ppt如何压缩变小
  12. 第一章 机器学习(浙大胡浩基教授)
  13. Android 渠道抽成,内容为主,渠道为辅,国内Android商店何时才能调整分成比?
  14. Android - 接收、监听系统短信广播
  15. 掌握盲打?写个脚本陪自己练,每天练一遍,基本上一个星期就成了!
  16. excel表格的上传和下载
  17. Annotate点云标注工具
  18. 安卓Apk安装出错:更新包与已安装应用的签名不一致,但在应用管理中却找不到这个已经卸载的应用
  19. 问答推广技巧和注意事项问答平台推广的执行方案
  20. PLM是做题家吗?一文速览预训练语言模型数学推理能力新进展

热门文章

  1. watch与watchEffect区别 watch与computed区别
  2. Django视图优化(页面显示以及页面跳转)
  3. 【线段树_DFS序】POJ 3321 Apple Tree
  4. HTML5导航下划线,CSS导航下划线实现
  5. Android弹出自定义Dialog,android自定义Dialog实现底部弹窗
  6. 自建自定义短网址,可自定义域名,可统计点击数、来源
  7. IT企业法律风险防范 -----你准备好了吗?
  8. Kafka-Listener配置参数、配置公网访问以及可能出现的问题
  9. 468,提莫攻击的两种解决方式
  10. “新冠肺炎”会让远程移动办公成为很酷的工作方式?