1179 Chemical Equation(搜索 + 回溯)

 先把各产物对应的公式按题面要求的从小到大进行排序(丢set里让他自己排序就行),搜索条件有两个:

  1.每个原料最多使用一次

  2.每个产物都要被生成

排序后,搜索得到的第一个解就是最优解。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n, m, k;
 4 vector<string> products(25); //按序记录产物
 5 map<string, set<vector<string>>> equation; //记录所有公式
 6 map<string, bool> possess; //是否拥有该原料
 7 
 8 void output(map<string, set<string>> result) {
 9     for (int i = 0; i < m; ++ i) {
10         auto j = result.find(products[i]);
11         if (j == result.end()) continue;
12         int index = 0;
13         for (auto l : j -> second) {
14             cout << l;
15             index ++;
16             if (index != j -> second.size()) {
17                 cout << " + ";
18             }
19         }
20         cout << " -> " << products[i] << endl;
21     }
22 }
23 void back_travel(int start, map<string, set<string>> solution) {
24     if (solution.size() == m) {
25         output(solution);
26         exit(0); //不用继续回溯,按顺序找到的第一个就是最优解
27         return;
28     }
29     auto iter = equation.find(products[start]);
30     for (auto i : iter -> second) {
31         bool is_enough = true;
32         for (auto j : i) {
33             if (!possess[j]) {
34                 is_enough = false;
35                 break;
36             }
37         }
38         if (is_enough) {
39             map<string, set<string>> temp = solution;
40             for (auto j : i) {
41                 possess[j] = false;
42                 temp[products[start]].insert(j);
43             }
44             back_travel(start + 1, temp);
45             for (auto j : i) { 
46                 possess[j] = true;
47             }
48         }
49     }
50 }
51 int main() {
52     cin >> n;
53     for (int i = 0; i < n; ++ i) {
54         string reactant;
55         cin >> reactant;
56         possess[reactant] = true;
57     }
58     cin >> m;
59     for (int i = 0; i < m; ++ i) {
60         cin >> products[i];
61         vector<string> temp_s;
62         temp_s.push_back(products[i]);
63         equation[products[i]].insert(temp_s); //将x->x添加到公式中
64     }
65     cin >> k;
66     for (int i = 0; i < k; ++ i) {
67         vector<string> temp_s;
68         string temp;
69         while(cin >> temp) {
70             if (temp == "->") {
71                 break;
72             } else if (temp == "+") {
73                 continue;
74             }
75             temp_s.push_back(temp);
76         }
77         cin >> temp;
78         equation[temp].insert(temp_s);
79     }
80     back_travel(0, {});
81 }

 

posted on 2024-11-28 20:48  Coder何  阅读(69)  评论(0)    收藏  举报