题解:小红的魔法药剂(贪心策略)

题目大意

小红想要收集编号从 种魔法药剂,每种药剂有两种形态:红色版本 和 蓝色版本。她只需要每种药剂拥有任意一种形态即可。

获取方式有两种:

  1. 直接购买红色药剂:第 种红色药剂花费 金币。
  2. 调配合成蓝色药剂:若已拥有红色的第 和第 种药剂,可以消耗这两瓶红色药剂来合成一瓶蓝色的第 种药剂,合成过程不额外花钱。

目标是:最小化总金币花费,使得每种药剂至少有一种形态(红或蓝)。

输入输出示例解析

输入:

5 2 4 10 1 3 2 3 4 5 1 2 2 5 1 4

输出:

16

说明:

可以直接买红色药剂,或者通过合成获得蓝色药剂。 对于第 种药剂,我们有两种选择: 花费 金币买红色版本; 或者不买红色,但为了合成蓝色版本,需要先买红色的 ,合成成本为

观察题目要求:我们只需要每种药剂至少有一个形态。也就是说,对于第 种药剂,我们要么买红色,要么合成蓝色,二者选其一。

关键在于:是否可以独立地对每种药剂做决策?

核心思路:贪心策略

我们发现,虽然合成蓝色药剂依赖其他红色药剂,但题目结构是: 每个药剂 的蓝色版本只能通过红色药剂 合成。 我们可以选择:买红色 ,或者 不买红色 ,但必须保证红色 和红色 被购买(用于合成蓝色 )。

但是,如果每个药剂都独立决策“买红”还是“合蓝”,会存在资源复用的问题:比如红色药剂 可能被多个合成过程需要。

然而,本题的关键洞察是: 我们可以贪心地为每种药剂 独立决策: 要么花费 买红色; 要么花费 来支持合成蓝色(即必须买 的红色); 取两者最小值。

代码实现

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner reader = new Scanner(System.in);

		int n = reader.nextInt();
		int[] arr = new int[n];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = reader.nextInt();
		}
		int[] brr = new int[n];
		for (int i = 0; i < brr.length; i++) {
			int x = reader.nextInt() - 1;
			int y = reader.nextInt() - 1;
			brr[i] = arr[x] + arr[y];
		}

		long cost = 0;
		for (int i = 0; i < brr.length; i++) {
			cost += Math.min(arr[i], brr[i]);
		}
		System.out.println(cost);

		reader.close();
	}

}

总结

项目 内容

题目 小红的魔法药剂 算法 贪心

注意事项 合成会消耗原料,但贪心在本题数据下仍成立

时间复杂度

空间复杂度