• 给定一个数组arr,长度为N且每个值都是正数,代表N个人的体重。再给定一个正数 limit,代表一艘船的载重。


    问题描述:

            给定一个数组arr,长度为N且每个值都是正数,代表N个人的体重。再给定一个正数 limit,代表一艘船的载重。

            以下是坐船规则:

    1. 每艘船最多只能做两人。
    2. 乘客 的体重和不能超过limit。

            返回如果同时让这N个人过河最少需要几条船。 

    思想:

            首先把整个数组进行排序,若数组中出现大于limit的数字,则无法过河,直接返回-1。

    普遍情况算法流程:

    1.找到小于等于limit一半的数位置L,另一半指针为R= L+1。

    2.从L开始和R位置的数进行配对。

            2.1 如果L位置的数和R位置上的数加起来大于limit,那么R位置保持不变,L位置向左移动一位,原本L位置的数字为X类型数字。

            2.2 如果L位置的数和R位置上的数加起来小于等于limit,那么移动R位置,查看R右半部分宫有几个数字和L位置数字匹配满足条件。我们就找到了一批匹配的数字,记录右部分移动了几位,左半部分也相应的移动几位。这类型的人员用√表示。

            2.3 在2.2中若右半部分找不到匹配的数字,则L向左移动一位,原本L位置的数字为X类型数字。

            2.4 最后结果可能分为两种情况:左侧先匹配完和右侧先匹配完。当左侧先匹配完时,右侧剩下的数字每个人一条船。当右侧先匹配完时,左侧剩下的每个人都是X类型。

    3. X类型人员两人乘一艘船,√号类型人员左半部分和右半部分搭配乘一条船,右侧剩下的人员每个人乘一条船。最后的结果是这三类人员相加和。

    代码:

    1. public static int minBost(int[] arr, int limit) {
    2. if (arr == null || arr.length == 0) {
    3. return 0;
    4. }
    5. int N = arr.length;
    6. if (arr[N - 1] > limit) {
    7. return -1;
    8. }
    9. int lessR = -1;
    10. //所有人的体重都不超过limit
    11. // <= limit/2 最右的位置
    12. for (int i = N - 1; i >= 0; i--) {
    13. if (arr[i] <= (limit / 2)) {
    14. lessR = i;
    15. break;
    16. }
    17. }
    18. if (lessR == -1) {
    19. return N;
    20. }
    21. int L = lessR;
    22. int R = lessR + 1;
    23. int noUsed = 0;//画X的数量统计
    24. while (L >= 0) {
    25. int solved = 0;//此时的[L],让R画过了几个数
    26. while (R < N && arr[L] + arr[R] <= limit) {
    27. R++;
    28. solved++;
    29. }
    30. //R来到不达标的位置
    31. if (solved == 0) {
    32. noUsed++;
    33. L--;
    34. } else {//此时的[L],让R画过的solved个数
    35. L = Math.max(-1, L - solved);
    36. }
    37. }
    38. //左半区总个数 <=limit/2的区域
    39. int all = lessR + 1;
    40. //画对号的量
    41. int used = all - noUsed;
    42. // >limit/2区域中,没搞定的数量
    43. int moreUnsolved = (N - all) - used;
    44. return used + ((noUsed + 1) >> 1) + moreUnsolved;
    45. }
    46. public static void main(String[] args) {
    47. int[] arr = {1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5};
    48. int weight = 6;
    49. System.out.println(minBost(arr, weight));
    50. }

  • 相关阅读:
    cell-var-from-loop
    典型行业大数据应用和安全风险和解决方案
    三字经||无聊数了下三字经的字数
    神经网络时间序列分析,神经网络模型可解释性
    图解LeetCode——1779. 找到最近的有相同 X 或 Y 坐标的点(难度:简单)
    二分图 二分图最大匹配
    NXP i.MX8系列平台开发讲解 - 3.10 Linux PCIe资源分配与访问(二)
    Node.js之Express快速介绍与入门示例
    TikTok Shop新结算政策:卖家选择权加强,电商市场蓄势待发
    Reference for Ruijie Switch Configuration
  • 原文地址:https://blog.csdn.net/z1171127310/article/details/128173785