大家好,我是晴天学长,这是很重要的贪心思维题,哈希的存法和小根堆的表示很重要。
1) .通关
2) .算法思路
通关
用hash(int[])存点的子节点并按输入顺序存关卡的号码(输入顺序就是)
列如:key:父节点
难度 经验 关卡
优先队列存难度和节点
1.接受数据和初始经验。(用快读)。
2.判断第1关能过不。
3.把第1关的子节点放入队列
4.从队列中取出元素
5.挑战成功再把子元素丢入队列中
6.ans++;
3).算法步骤
1.从输入中读取关卡数量 n 和初始经验值 sum。
2.读取第一关的难度、关卡和经验值,并将其存储在map中。
3.如果初始经验值小于第一关的经验值要求,则输出0并返回。
4.增加初始经验值并增加答案计数器。
5.循环读取剩余的关卡信息,并将其存储在map中。
6.创建一个小顶堆(优先队列)queue,并将第一关的子节点放入小顶堆。
7.循环处理小顶堆中的关卡节点,直到小顶堆为空。
8.从小顶堆中取出一个关卡节点,比较当前经验值是否小于关卡节点的难度要求,如果是,则输出答案计数器并返回。
9.增加经验值并增加答案计数器。
10.如果当前关卡有子节点,则将子节点放入小顶堆。
11.输出最终的答案计数器。
4). 代码实例
java
package LanQiaoTest.大小堆;
import java.util.*;
//变种广搜
public class 通关_小顶堆 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Map<Integer, List<int[]>> map = new HashMap<>();
//关卡
int ans = 0;
int n = scanner.nextInt();
//经验值
int sum = scanner.nextInt();
//存第一关
int temp = scanner.nextInt();
int temp1 = scanner.nextInt();
int temp2 = scanner.nextInt();
map.put(temp, new ArrayList<>());
map.get(temp).add(new int[]{0, temp1, temp2});
int[] temp3 = map.get(temp).get(0);
if (sum < temp3[2]) {
System.out.println(ans);
return;
}
sum += temp3[1];
ans++;
//存子节点了
for (int i = 1; i < n; i++) {
//父节点
int a = scanner.nextInt();
//挑战成功的经验值
int b = scanner.nextInt();
//难度
int c = scanner.nextInt();
if (!map.containsKey(a)) {
map.put(a, new ArrayList<>());
}
//父节点 难度 关卡 经验值
map.get(a).add(new int[]{c, i + 1, b});
}
//用优先队列(默认小根堆)
PriorityQueue<Integer[]> queue = new PriorityQueue<>((a, b) -> (a[0] - b[0]));
//把第一关的子节点丢入小根堆
for (int i = 0; i < map.get(1).size(); i++) {
int[] temp4 = map.get(1).get(i);
//难度 关卡 经验值
queue.offer(new Integer[]{temp4[0], temp4[1], temp4[2]});
}
// 开始闯关
while (!queue.isEmpty()) {
//难度 关卡 经验值
Integer[] temp5 = queue.poll();
//对比
if (sum < temp5[0]) {
System.out.println(ans);
return;
}
sum += temp5[2];
ans++;
//把闯的关的子节点丢入小根堆
if (map.containsKey(temp5[1])) {
for (int i = 0; i < map.get(temp5[1]).size(); i++) {
int[] temp6 = map.get(temp5[1]).get(i);
queue.offer(new Integer[]{temp6[0], temp6[1], temp6[2]});
}
}
}
System.out.println(ans);
scanner.close();
}
}
4).总结
- 小根堆的表示(在贪心题中经常使用)
- 哈希表的正确使用。