华为OD机试 - 组装最大可靠性设备(Java)
题目描述
一个设备由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
- 0 <=N <=100
- 0 <=type <=N-1
- 0 <=total <=100000
- 0 <reliability <=100000
用例
输入 | 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 |
输入 | 100 1 1 0 90 200 |
输出 | -1 |
说明 | 组成设备需要1个元件 ,但是元件价格大于预算 ,因此无法组成设备 ,返回-1 |
题目解析
本题很像是分组背包问题 ,但是细看却不是 ,因为题目描述中说 :
每种类型元器件都需要购买一个
我的思路是笛卡尔积,比较暴力不知道能不能通过
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int money = in.nextInt();
int kindnum = in.nextInt();
int n = in.nextInt();
ArrayList<ArrayList<Item>> kinds = new ArrayList<>();
for (int i = 0; i < kindnum; i++) {
kinds.add(new ArrayList<>());
}
for (int i = 0; i < n; i++) {
int type = in.nextInt();
int reliability = in.nextInt();
int price = in.nextInt();
kinds.get(type).add(new Item(reliability,price));
}
for (ArrayList<Item> kind : kinds) {
kind.sort((a,b)->(a.reliability- b.reliability));
}
ArrayList<Item> resultSet = new ArrayList<>();
ArrayList<Item> items = kinds.get(0);
resultSet.add(new Item(items.get(items.size()-1).reliability,0));
for (int i = 0; i < kinds.size(); i++) {
resultSet = Descartes(resultSet,kinds.get(i));
}
resultSet.sort((a,b)->(b.reliability)- a.reliability);
int result = -1;
for (Item item : resultSet) {
if(item.price <= money){
result = item.reliability;
break;
}
}
System.out.println(result);
}
public static ArrayList<Item> Descartes(ArrayList<Item> As,ArrayList<Item> Bs){
ArrayList<Item> items = new ArrayList<>();
for (Item a : As) {
for (Item b : Bs) {
items.add(new Item(a.reliability > b.reliability ? b.reliability : a.reliability,a.price+ b.price));
}
}
return items;
}
public static class Item{
int reliability;
int price;
public Item(int reliability, int price) {
this.reliability = reliability;
this.price = price;
}
@Override
public String toString() {
return "Item{" +
"reliability=" + reliability +
", price=" + price +
'}';
}
}
}