【二分法】组装最大可靠性设备

import java.io.*;
import java.util.*;

/**
 * 组装最大可靠性设备
 * 一个设备由N种元器件组成,每种类型元器件只需要一个,类型type编号范围0~N-1,每个元器件由可靠性属性reliability,
 * 可靠性越高价格越贵,设备的可靠性由组成设备的所有器件中可靠性最低的器件决定。给定预算S,购买N种元器件
 * 每种类型元器件都需要购买一个,在不超过预算的情况下,请给出能够组成的设备的最大可靠性
 * 500 3           //500表示总预算,3表示元器件的种类
 * 6               //元器件的总数
 * 0 80 100        //0表示元器件类型编号,80表示元器件可靠性,100代表元器件的价格
 * 输出描述:符合预算的设备的最大可靠性,如果预算无法买下N种器件,返回-1
 */
public class AssemblyOfMaximumReliabilityEquipment {
    /*
        500 3
        6
        0 90 200
        0 80 100
        1 70 210
        1 50 50
        2 50 100
        2 60 150
        ----------------
        60
        ++++++++++++++++
        100 1
        1
        0 90 200
        ----------------
        -1
     */
    private static String line;
    private static String[] strArr;
    private static int[] nums;
    /**
     * 元器件目录,索引值代表元器件类型编号,列表代表该类型编号下的元器件,a[0]表示元器件可靠性,a[1]表示元器件价格
     */
    private static List<List<int[]>> categories = new ArrayList<>();
    /**
     * 可靠性列表,排重之后升序排列
     */
    private static Set<Integer> reliabilitySet = new TreeSet<>();
    /**
     * 可靠性列表
     */
    private static List<Integer> reliabilityList = new ArrayList<>();
    /**
     * 总预算
     */
    private static int budget;
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        line = in.readLine();
        strArr = line.split(" ");
        nums = Arrays.stream(strArr).mapToInt(Integer::parseInt).toArray();
        budget = nums[0];
        //元器件种类总数
        int typeCount = nums[1];
        line = in.readLine();
        //元器件总数
        int count = Integer.parseInt(line);

        for (int i = 0; i < typeCount; i++) {
            categories.add(new ArrayList<>());
        }

        for (int i = 0; i < count; i++) {
            line = in.readLine();
            strArr = line.split(" ");
            nums = Arrays.stream(strArr).mapToInt(Integer::parseInt).toArray();
            //元器件种类编号
            int type = nums[0];
            //元器件可靠性
            int reliability = nums[1];
            //元器件价格
            int cost = nums[2];
            categories.get(type).add(new int[]{reliability,cost});
            reliabilitySet.add(reliability);
        }

        out.println(determineMaxReliability());
        out.flush();
        in.close();
        out.close();
    }

    /**
     * 在不超出预算的前提下,找到最大可靠性元器件
     * @return      符合预算的设备的最大可靠性,如果预算无法买下N种器件,返回-1
     */
    public static int determineMaxReliability() {
        //所有可靠性排重后升序排序,加入列表
        reliabilityList.addAll(reliabilitySet);
        //确定可靠性的二分边界
        int low = 0, high = reliabilityList.size() - 1;
        int result = -1;
        //开始二分循环
        while (low <= high) {
            int mid = low + (high - low) / 2;
            //以中点可靠性为目标,预算不超,则认为当前位置可满足,取对应可靠性值即可
            Integer target = reliabilityList.get(mid);
            if (budgetIsEnough(target)) {
                result = reliabilityList.get(mid);
                low = mid + 1;
            } else {
                high = mid - 1;
            }
        }
        return result;
    }

    /**
     * 按照目标可靠性查找元器件
     * @param targetReliability     目标可靠性
     * @return                      是否超预算
     */
    private static boolean budgetIsEnough(int targetReliability) {
        //总成本初始化为0
        int totalCost = 0;
        //遍历元器件目录
        for (List<int[]> category : categories) {
            //逐个型号查找,在目标可靠性下的最低价格
            int minCostForTarget = findClosestComponent(category, targetReliability);
            //单个超预算,则返回假
            if (minCostForTarget == -1) {
                return false;
            }
            //单个不超预算,则总成本加入当前元器件价格
            totalCost += minCostForTarget;
        }
        //判断总成本是否超预算
        return totalCost <= budget;
    }

    /**
     * 找到最接近目标可靠性的元器件
     * @param category              元器件列表
     * @param targetReliability     目标可靠性
     * @return                      元器件价格
     */
    private static int findClosestComponent(List<int[]> category, int targetReliability) {
        //对目录中的元器件按可靠性升序排序
        category.sort((a,b) -> a[0] - b[0]);
        //确立二分边界
        int low = 0, high = category.size() - 1;
        //循环二分
        while (low <= high) {
            int mid = low + (high - low) / 2;
            //获得当前可靠性
            int currentReliability = category.get(mid)[0];
            //找到最接近目标的可靠性值,记录对应坐标
            if (currentReliability < targetReliability) {
                low = mid + 1;
            } else {
                high = mid - 1;
            }
        }
        //最终坐标值不越界且可靠性值大于等于目标值,则返回其成本,否则返回-1
        boolean isValid = low < category.size() && category.get(low)[0] >= targetReliability;
        if(isValid){
            return category.get(low)[1];
        }else {
            return -1;
        }
    }
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值