华为OD题目:统一限载货物数最小值

华为OD机试 - 统一限载货物数最小值

题目描述
火车站附近的货物中转站负责将到站货物运往仓库,小明在中转站负责调度2K辆中转车K辆干货中转车,K辆湿货中转车)。货物由不同供货商从各地发来,各地的货物是依次进站,然后小明按照卸货顺序依次装货到中转车,一个供货商的货只能装到一辆车上不能拆装,但是一辆车可以装多家供货商的货;
中转车的限载货物量由小明统一指定,在完成货物中转的前提下,请问中转车的统一限载货物数最小值为多少
输入描述
。第一行 length 表示供货商数量 1 <= length <= 10^4
第二行 goods 表示供货数数组 1 <= goods <= 10^4o
第三行 types表示对应货物类型,types[等于0或者1,:其中0代表干货,1代表湿货
第四行 k表示单类中转车数量 1 <= k <= goods.length
输出描述
运行结果输出一个整数,表示中转车统一限载货物数
备注
中转车最多跑一趟仓库

示例1
输入:
4
3 2 6 3
0 1 1 0
2

输出:
6

说明:
货物1和货物4为干货,由2两干货中转车中转,每辆车运输一个货物,限载为3
货物2和货物3为湿货,由2两湿货中转车中转,每辆车运输一个货物,限载为6
这样中转车统一限载货物数可以设置为6(千货车和湿货车限载最大值),是最小的取值
示例2
输入:
4
3 2 6 8
0 1 1 1
1
输出:
16

说明:
货物1为千货,由1两工货中转车中转,限载为3
货物2、货物3和货物4为湿货,由1两湿货中转车中转,限载为16
这样中转车统一限载货物数可以设置为16 (千货车和湿货车限载最大值),是最小的取值

public class My {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String lenStr = sc.nextLine();
        int len = Integer.parseInt(lenStr);


        String[] strings = sc.nextLine().split(" ");
        int[] goods = Arrays.stream(strings).mapToInt(Integer::parseInt).toArray();

        String[] typeStr = sc.nextLine().split(" ");
        int[] types = Arrays.stream(typeStr).mapToInt(Integer::parseInt).toArray();

        int k = Integer.parseInt(sc.nextLine());
        int result = getResult(len, goods, types, k);
        System.out.println(result);

    }

    public static int getResult(int len, int[] goods, int[] types, int k) {
        int left = 0;
        int right = 0;
        for (int i = 0; i < len; i++) {
            left = Math.max(left, goods[i]);
            right += goods[i];
        }

        while (left < right) {
            int mid = (left + right) / 2;
            if (canDivide(len, goods, types, k, mid)) {
                right = mid;
            }else {
                left = mid + 1;
            }
        }
        return left;

    }

    public static boolean canDivide(int len, int[] goods, int[] types, int k, int limit) {
        int dryCount = 0;
        int wetCount = 0;
        int drySum = 0;
        int wetSum = 0;

        for (int i = 0; i < len; i++) {
            //0-干货, 1-湿货
            if (types[i] == 0) {
                //看这一批 加上 当前货物是否在容量内
                if (drySum + goods[i] <= limit) {
                    drySum += goods[i];
                }else {
                    //如果超出容量了,则需要再加车
                    if (dryCount + 1 == k) {
                        // 没有可用的干货车了,则说明此limit无法完成所有货物的运输,直接返回false
                        return false;
                    }else {
                        // 有可用的干货车,则说明已用掉的干货车数量dryCarCount++,新的干货车装入当前货物goods[i]
                        dryCount++;
                        drySum = goods[i];
                    }
                }
            }else {
                if (wetSum + goods[i] <= limit) {
                    wetSum += goods[i];
                }else {
                    if (wetCount + 1 == k) {
                        return false;
                    }else {
                        wetCount++;
                        wetSum = goods[i];
                    }
                }
            }
        }
        return true;
    }

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值