组装最大可靠性设备

题目描述

一个设备由 N 种类型元器件组成(每种类型元器件只需要一个,类型 type 编号从 0~N-1 ),每个元器件均有可靠性属性 reliability,可靠性越高的器件其价格 price 越贵。而设备的可靠性由组成设备的所有器件中可靠性最低的器件决定。给定预算 S,购买 N 种元器件(每种类型元器件都需要购买一个),在不超过预算的情况下,请给出能够组成的设备的最大可靠性。

输入描述

S N // S总的预算,N元器件的种类

total // 元器件的总数,每种型号的元器件可以有多种;

此后有total行具体器件的数据

type reliability price //type 整数类型,代表元器件的类型编号从0~N-1; reliabilty 整数类型,代表元器件的可靠性;price 整数类型 ,代表元器件的价格

输出描述

符合预算的设备的最大可靠性,如果预算无法买齐N种器件,则返回-1

备注

  • 0≤S.price≤ 10000000

  • O≤N≤ 100

  • 0≤ type ≤ N-1

  • 0≤total≤ 100000

  • 0<reliability≤100000

示例1

输入

500 3
6
0 80 100
0 90 200
1 50 50
1 70 210
2 50 100
2 60 150

输出

60

说明

预算500,设备需要3种元件组成,方案类型0的第一个(可靠性80),类型1的第二个(可靠性70),类型2的第二个(可靠性60),可以使设备的可靠性最大 60

示例2

输入

100 1
1
0 90 200

输出

-1

说明
组成设备需要1个元件,但是元件价格大于预算,因此无法组成设备,返回-1

题解

按照可靠度排序,
从最小的可靠度依次尝试,直到不符合要求

源码Java

import java.io.InputStream;
import java.io.StringBufferInputStream;
import java.util.*;

public class Equipment {

	public static void main(String[] args) {
		InputStream inputStream = new StringBufferInputStream("500 3\n" +
				"6\n" +
				"0 80 100\n" +
				"0 90 200\n" +
				"1 50 50\n" +
				"1 70 210\n" +
				"2 50 100\n" +
				"2 60 150");
		inputStream = new StringBufferInputStream("100 1\n" +
				"1\n" +
				"0 90 200");
		Scanner scanner = new Scanner(inputStream);
		String[] split = scanner.nextLine().split(" ");
		Integer total = Integer.parseInt(split[0]);
		Integer buy = Integer.parseInt(split[1]);
		Integer sell = Integer.parseInt(scanner.nextLine());

		List<Equip> list = new ArrayList<>();
		for (int i = 0; i < sell; i++) {
			String[] ss = scanner.nextLine().split(" ");
			list.add(new Equip(Integer.parseInt(ss[0]), Integer.parseInt(ss[ 1]), Integer.parseInt(ss[2])));
		}
		Collections.sort(list);

		int max = -1;
		for (int i = 0; i < list.size(); i++) {
			int buy1 = buy(list, buy, total, i);
			if (buy1 < 0) {
				break;
			}
			max = Math.max(max, buy1);
		}
		System.out.println(max);

	}

	public static int buy(List<Equip> list, int buy, int total, int start) {
		Map<Integer, Equip> map = new HashMap<>();
		int result = list.get(start).reliability;
		for (int i = start; i < list.size(); i++) {
			Equip equip = list.get(i);
			Equip equip1 = map.get(equip.type);
			if (equip1 == null) {
				map.put(equip.type, equip);
				if (map.size() == buy) {
					break;
				}
			}
		}
		if (map.size() == buy) {
			int spent = 0;
			for (Map.Entry<Integer, Equip> entry : map.entrySet()) {
				spent += entry.getValue().price;
			}
			if (spent > total) {
				return -1;
			}
		} else {
			if (map.size() != buy) {
				return -1;
			}
		}
		return result;
	}

	static class Equip implements Comparable<Equip>{
		public int type;
		public int reliability;
		public int price;

		public Equip(int type, int reliability, int price) {
			this.type = type;
			this.reliability = reliability;
			this.price = price;
		}

		public int compareTo(Equip o) {
			if (this.reliability == o.reliability) {
				return this.price - o.price;
			}
			return this.reliability - o.reliability;
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坚定的小辣鸡在努力

你的支持是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值