题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2677
题目的意思大概说一下:
就相当于LOL,如果你想买一把破败,你背包中只有一把吸血鬼节杖,问你还需要多少钱?
那就从最终需要的装备开始推,dfs的思维是:首先判断你背包中有没有你想要的装备,没有就去商店买(商店只有最原始的东西,如:短剑,长剑,草鞋等),如果商店都没有,那就合成(合成不需要费用,但是你要先获得他合成需要的东西)。
递归的语义是:获取一件装备需要花费多上钱
值得注意的是,这道题的输入也不太好处理,(不知道C++该怎么处理)
下面的源代码,代码中有比较多的注释,容易理解:
import java.util.HashMap;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()) {
int kind_of_equip = sc.nextInt();
HashMap<String,Double> shop = new HashMap<>();//商店,存放装备的名称和价格
for (int i = 0; i < kind_of_equip; i++) {
String name = sc.next();
if (!shop.containsKey(name)) {
shop.put(name,sc.nextDouble());
}
}
// for test
// for (String s: shop.keySet()) {
// System.out.println(s + ":" + shop.get(s));
// }
int has_kind = sc.nextInt();//拥有的装备的种类
HashMap<String,Integer> bag = new HashMap<>();//背包,存放目前有的装备和数量
for (int i = 0; i < has_kind; i++) {
String name = sc.next();
if (!bag.containsKey(name)) {
bag.put(name,sc.nextInt());
}
}
// for test
// for (String s: bag.keySet()) {
// System.out.println(s + ":" + bag.get(s));
// }
int nums_of_formula = sc.nextInt();
sc.nextLine();//注意要“吃掉”后面的那个回车
HashMap<String, String[]> path = new HashMap<>(); //装备的合成路径
for (int i = 0; i < nums_of_formula; i++) {
String t = sc.nextLine();
String[] s = t.split(" = "); //一个式子只有一个等号,所以必定划分为两个部分
String[] parts = s[0].split(" \\+ "); //需要转义
path.put(s[1],parts);
}
// for test
// for (String s: path.keySet()) {
// System.out.println();
// System.out.print(s + ":" );
// String[] ss = path.get(s);
// for (int i = 0; i < ss.length; i++) {
// System.out.print(ss[i] + " ");
// }
// Sys
// tem.out.println();
// }
int kind_of_need = sc.nextInt();
HashMap<String,Integer> needs = new HashMap<>();
for (int i = 0; i < kind_of_need; i++) {
String name = sc.next();
int nums = sc.nextInt();
if (nums != 0) {//不知道有没有这个坑,先避一下
needs.put(name,nums);
}
}
double money = 0;//表示最后需要花费的钱
for (String s: needs.keySet()) { //从需要购买的装备中拿出一件
while(needs.get(s) != 0) {
money += dfs(s,0,shop,bag,path);
needs.put(s,needs.get(s)-1);
}
}
System.out.println((int)money);
}
}
public static double dfs(String name, double price, HashMap<String,Double> shop, HashMap<String,Integer> bag, HashMap<String,String[]> path) {
if (bag.containsKey(name)) { //如果背包里就有,那就不用去买了,需要将背包中的装备减掉
bag.put(name,bag.get(name)-1);//该装备的数量减1
if (bag.get(name) == 0) {
bag.remove(name);
}
return 0;
}
if(shop.containsKey(name)) {//如果商店有,就证明不需要再合成了,直接购买就行了
return shop.get(name);
}
//如果到现在都还没有return,就证明需要合成,那就递归的去调用就好了
String[] parts = path.get(name);
for (int i = 0; i < parts.length; i++) {
price+=dfs(parts[i],0,shop,bag,path);
}
return price;
}
}