切割绳子问题(附 java 代码)
问题:
有N条绳子,它们的长度分别Li,i=1,⋯,N。如果从它们中切割出K条长度相同的绳子,这K条绳子每条最长能有多长?(我们这里考虑每条绳子的长度都是整数,切最后切割出来的绳子的长度也是整数。如果遇到的问题绳子长度不是整数类型,可将绳子的长度先扩大10n 倍,转换成整数形式 )
解题思路:
这个题需要用二分查找法来解决,为了方便讲解,我们假设绳子有4条,长度分别是{802,743,457,539},需要切割出11条长度相同的绳子(这个数据来自PTA 切割绳子问题)
就我的理解,既然是用二分查找,那么就需要设置一个较为合适的区间[left right],将答案包括在这个区间里,那么我们就要先去把这样一个区间找出来。
//这下面的操作就是去寻找出这个区间 int left = 1;//理论上切割出绳子的最小值 int right = 10000;//理论上切割出绳子的最大值 for (int i = 0; i < n; i++) {ints[i] = scanner.nextInt();//读取每绳子的长度,并存入ints 数组内if (ints[i] < right){right = ints[i];//将最短的那条绳子的长度赋给 right} } //去调整left 和 right 的值,找到包含最优解的一个较为合适的区间 int res = 0;//res 表示切割出绳子的数量 for (int i = 0; i < n; i++) {//这个循环是去求当切割长度为right时,切割出来的绳子数量res += ints[i] / right; } while (res>=k){//这个循环是为了使得当切割长度为right时,切割出来的绳子数量小于所需要的绳子数量res = 0;int temp = right;right = right*2;left = temp;for (int i = 0; i < n; i++) {res += ints[i] / right;} }
在找到一个较为合适的区间[left right]后,就利用二分查找法去求出一个较优的解
//寻找一个较优值 int mid = 0;//区间的中间值 while (res != k){//二分查找经典做法,根据条件去缩小区间res = 0;mid = (right-left)/2+left;for (int i = 0; i < n; i++) {res += ints[i] / mid;}if (res<k){right = mid;}else if (res>k){left=mid;} }
根据所需要的精度,让之前求出的较优值去逐渐靠近最优质的
while (true){//因为是求最大值,所以我们不断的去增加之前求出的较优值,直到这个值不再满足我们所需要的条件mid++;int res01 = 0;for (int i = 0; i < n; i++) {res01 += ints[i] / mid;}if (res01 != k){mid--;break;} }
完整代码
public static void main(String[] args) { //这部分操作是输入数据并将输入的 N 条绳子的长度 Len 存入一个整数数组里Scanner scanner = new Scanner(System.in);String str = scanner.nextLine();String[] strArr = str.split(" ");int n = Integer.parseInt(strArr[0]);int k = Integer.parseInt(strArr[1]);int[] ints = new int[n]; //设置左右区间,将最短的那根绳子设为右边界int left = 1;int right = 10000;for (int i = 0; i < n; i++) {ints[i] = scanner.nextInt();if (ints[i] < right){right = ints[i];}}scanner.close(); //改变left 和 right 的值,使最优解放在区间内int res = 0;for (int i = 0; i < n; i++) {res += ints[i] / right;}while (res>=k){res = 0;int temp = right;right = right*2;left = temp;for (int i = 0; i < n; i++) {res += ints[i] / right;}} //利用二分查找,找到一个较优的值int mid = 0;while (res != k){res = 0;mid = (right-left)/2+left;for (int i = 0; i < n; i++) {res += ints[i] / mid;}if (res<k){right = mid;}else if (res>k){left=mid;}} //因为求最大,所以逐渐将这一较优值增加,直到这一值不满足条件while (true){mid++;int res01 = 0;for (int i = 0; i < n; i++) {res01 += ints[i] / mid;}if (res01 != k){mid--;break;}}System.out.println(mid);}
总结
我在写代码的时候是按照我之前的步骤来的,在写完代码之后,我感觉这个代码写的有些冗余了,之后需要继续完善。
切割绳子问题(附 java 代码)相关推荐
- 转 | 禁忌搜索算法(Tabu Search)求解带时间窗的车辆路径规划问题详解(附Java代码)
以下文章来源于数据魔术师 ,作者周航 欲下载本文相关的代码及算例,请关注公众号[程序猿声],后台回复[TSVRPJAVA]不包括[]即可 前言 大家好呀! 眼看这9102年都快要过去了,小编也是越来越 ...
- Tabu Search求解作业车间调度问题(Job Shop Scheduling)-附Java代码
本文来源于公众号[程序猿声],作者舟寒丶 作业车间调度问题 问题模型 举个栗子 有关禁忌搜索算法的内容,公众号内有详细教程: 干货 |[算法]禁忌搜索算法(Tabu Search,TS)超详细通俗解析 ...
- 分支定界法解TSP问题(hungary算法定界)附java代码
本文章知识来自于微信公众号"数据魔术师",侵删. 感谢"数据魔术师"团队. 上一篇文章介绍了TSP问题.分支定界法.one-tree算法,有兴趣可以返过去看一下 ...
- 干货 | Tabu Search求解作业车间调度问题(Job Shop Scheduling)-附Java代码
本文来源于公众号[程序猿声],作者舟寒丶 作业车间调度问题 问题模型 举个栗子 有关禁忌搜索算法的内容,公众号内有详细教程: 干货 |[算法]禁忌搜索算法(Tabu Search,TS)超详细通俗解析 ...
- 4列的计算机代码,干货 | 10分钟带你彻底了解column generation(列生成)算法的原理附java代码...
OUTLINE 前言 预备知识预警 什么是column generation 相关概念科普 Cutting Stock Problem CG求解Cutting Stock Problem 列生成代码 ...
- 作业调度问题java代码_Tabu Search求解作业车间调度问题(Job Shop Scheduling)-附Java代码...
本文来源于公众号[程序猿声],作者舟寒丶 作业车间调度问题 问题模型 举个栗子 有关禁忌搜索算法的内容,公众号内有详细教程: 大家可以点击超链接回顾相关知识,这里就不再细说了. 一般而言,用禁忌搜索算 ...
- 图片转换为 latex 公式,识别图片中Latex公式,支持数学公式,化学公式,物理公式和生物公式,附Java代码和测试效果
目 录 1.编写Java代码实现识别图片中Latex公式 2.测试结果 3.源码下载 1.编写Java代码实现识别图片中Latex公式 直接上代码: public static String se ...
- java 路径规划_转 | 禁忌搜索算法(Tabu Search)求解带时间窗的车辆路径规划问题详解(附Java代码)...
以下文章来源于数据魔术师 ,作者周航 欲下载本文相关的代码及算例,请关注公众号[程序猿声],后台回复[TSVRPJAVA]不包括[]即可 前言 大家好呀! 眼看这9102年都快要过去了,小编也是越来越 ...
- 循环队列真的没那么难,就那么几个注意点,附Java代码及运行效果
1. 队列 队列是一种常见的线性数据结构,满足先进先出(First In First Out),简称为FIFO,第一次看到FIFO还以为是单片机的输出输出什么的,见笑了.数据结构不太了解的话可以看看我 ...
最新文章
- iOS下JS与OC互相调用(五)--UIWebView + WebViewJavascriptBridge
- java多递归调用_java – 递归调用方法
- iTerm2 for MacOS(终端模拟器/终端仿真器/命令终端工具)设置详解
- ★LeetCode(453)——最小移动次数使数组元素相等(JavaScript)
- 05 Confluent_Kafka权威指南 第五章: kafka内部实现原理
- Pytorch总结十五之优化算法:AdaGrad、RMSProp、AdaDelta、Adam算法详解
- 软件开发过程与项目管理(7.软件项目进度计划)
- LaTeX模板 - FORMCM
- insert on duplicate key update命令
- 用米粒填充国际棋盘python
- 八六、Linux 服务器+Nginx服务简介
- String类型转Long类型需要注意的问题
- Spring入门须知
- 复印机维修保养的常识
- AdvancedInstaller打包工具使用(五)
- TensorFlow 1.x 深度学习秘籍·翻译完成
- python打包exe之pyinstaller
- 微信小程序+Django—登录界面交互
- 微机原理与接口技术:DMA传输 详细笔记
- Go语言自学系列 | golang for循环语句