目录
E题 Set Meal
题目大意:
思路:(在求最大时和最小时,如果要求查询代价较小时,可以使用优先队列)
代码:
E题 Set Meal
E - Set Meal (atcoder.jp)
题目大意:
先给出n个主菜,m个配菜,然后ai(1<=i<=n)为第i个主菜的价值,bj(1<=j<=m)为第j个配菜的价值,然后套餐的定义是一个主菜一个配菜,问这n个主菜和m个配菜组成的套餐中,最贵的套餐是多少钱,其中有L个套餐组合是不合法的。
思路:(在求最大时和最小时,如果要求查询代价较小时,可以使用优先队列)
这道题其实很简单,主要难点就是如何存放这L个不合法的数据,让其在寻优的时候方便查询,这里用到的是HashSet。
寻优的方法,先将配菜进行排序,然后n个主菜都与最贵的配菜进行配对,这个配对组合使用优先队列(大根堆) 来进行存放,弹出的栈顶元素就是当前最贵套餐,弹出后判断是否为合法套餐,如果不是则让这个主菜,继续与下一个配菜配对并加入优先队列。
代码:
import java.util.*;/*** @ProjectName: study3* @FileName: Ex38* @author:HWJ* @Data: 2023/12/3 10:10*/
public class Ex38 {public static void main(String[] args) {Scanner input = new Scanner(System.in);int n = input.nextInt();int m = input.nextInt();long l = input.nextLong();HashSet<Node> nodes = new HashSet<Node>();int[] a = new int[n + 1];int[][] b = new int[m + 1][2];for (int i = 0; i < n; i++) {a[i + 1] = input.nextInt();}for (int i = 0; i < m; i++) {b[i + 1][0] = input.nextInt();b[i +1][1] = i+1;}for (int i = 0; i < l; i++) {int c = input.nextInt();int d = input.nextInt();nodes.add(new Node(c, d));}Arrays.sort(b, 1, m + 1,((o1, o2) -> {return o2[0] - o1[0];}));HashMap<Integer, Integer> map = new HashMap<>();for (int i = 1; i <= m; i++) {map.put(i, b[i][1]);}PriorityQueue<Node> nodes1 = new PriorityQueue<>(new Comparator<Node>() {@Overridepublic int compare(Node o1, Node o2) {return (a[o2.a] + b[o2.b][0]) - (a[o1.a] + b[o1.b][0]);}});for (int i = 1; i <= n; i++) {nodes1.add(new Node(i, 1));}while (true){Node cur = nodes1.poll();if (nodes.contains(new Node(cur.a, map.get(cur.b)))){if (cur.b == m) continue;else nodes1.add(new Node(cur.a, cur.b + 1));}else {System.out.println(a[cur.a] + b[cur.b][0]);break;}}}public static class Node{int a;int b;public Node(int a, int b) {this.a = a;this.b = b;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Node node = (Node) o;return a == node.a && b == node.b;}@Overridepublic int hashCode() {return Objects.hash(a, b);}}
}