#include <algorithm>
#include <iostream>
#include <fstream>
#include <set>
#include <vector>
#include <cassert>
#include <functional>
using namespace std;
#define PRINT_PROGRESS
struct drug_info_t
{
char name[64];
int require;
int block[2];
int effect[4];
};
const drug_info_t input[] =
{
/* id name require block effect */
/* 0 */ {"<null>", 0, {0, 0}, {+0, +0, +0, +0 }},
/* 1 */ {"AMPEA", 0, {13, 0}, {+14 +7, +15 +8 }},
/* 2 */ {"BMA", 0, {14, 22}, {+11, +15, +10, +16}},
/* 3 */ {"DXAMPEA", 0, {10, 23}, {+8, +7, +11, +11}},
/* 4 */ {"TST", 0, {17, 0}, {+7, +13, +15, +9 }},
/* 5 */ {"DHEA", 2, {15, 0}, {+13, +12, +9, +19}},
/* 6 */ {"THG", 0, {9, 20}, {+17, +17, +14, +8 }},
/* 7 */ {"anadrol", 4, {24, 0}, {+17, +14, +11, +14}},
/* 8 */ {"EPO", 1, {6, 0}, {+13, +0, +0, -2 }},
/* 9 */ {"argoxin", 8, {15, 0}, {+10, -1, +0, +0 }},
/* 10 */ {"atomoxetin", 9, {4, 19}, {+17, +0, +0, -4 }},
/* 11 */ {"bolasteron", 0, {16, 19}, {-1, +11, +0, -1 }},
/* 12 */ {"bolandiol", 11, {18, 0}, {-2, +8, +1, -3 }},
/* 13 */ {"calusteron", 12, {21, 0}, {+0, +10, +0, -2 }},
/* 14 */ {"danasol", 3, {18, 0}, {-2, +0, +15, +2 }},
/* 15 */ {"esiclen", 14, {5, 0}, {-1, +2, +10, +3 }},
/* 16 */ {"stanosolol", 15, {23, 0}, {+0, +0, +9, +5 }},
/* 17 */ {"gonadorelin", 0, {7, 0}, {+2, +1, -4, +16}},
/* 18 */ {"FGF", 17, {16, 20}, {-5, +1, +3, +8 }},
/* 19 */ {"formoterol", 18, {22, 0}, {+2, +0, +2, +14}},
/* 20 */ {"raloxiphen", 9, {5, 0}, {+0, +21, -15, -10}},
/* 21 */ {"cyclophenil", 12, {7, 0}, {+18, -19, +29, +20}},
/* 22 */ {"AMPK", 20, {2, 0}, {+22, +0, -10, +32}},
/* 23 */ {"albumin", 22, {4, 0}, {-10, +24, +30, +6 }},
/* 24 */ {"mannitol", 14, {10, 0}, {+38, +24, +0, -10}},
/* 25 */ {"IGF-1", 23, {19, 0}, {-10, +21, +28, +31}},
};
const int N = sizeof(input) / sizeof(drug_info_t);
using solution_t = array<int, N>;
int stats[4];
short blocked[N];
bool used[N] = {true};
vector<int> cur;
vector<solution_t> sol_list;
int best_score;
bool apply(int id)
{
auto const& d = input[id];
if (used[id] || blocked[id] || !used[d.require]) { return false; }
used[id] = true;
++blocked[d.block[0]];
++blocked[d.block[1]];
for (int i = 0; i < 4; ++i)
{
stats[i] += d.effect[i];
}
cur.push_back(id);
return true;
}
void cancel(int id)
{
auto const& d = input[id];
cur.pop_back();
for (int i = 0; i < 4; ++i)
{
stats[i] -= d.effect[i];
}
--blocked[d.block[1]];
--blocked[d.block[0]];
used[id] = false;
}
int score();
void optimize()
{
int s = score();
if (s > best_score)
{
sol_list.clear();
}
if (s >= best_score)
{
sol_list.emplace_back();
copy(cur.begin(), cur.end(), sol_list.back().begin());
best_score = s;
}
for (int id = 1; id < N; ++id)
{
#ifdef PRINT_PROGRESS
if (cur.empty())
{
cout << id << "/" << (N - 1);
}
else if (cur.size() == 1)
{
cout << ".";
}
#endif
if (apply(id))
{
optimize();
cancel(id);
}
#ifdef PRINT_PROGRESS
if (cur.empty())
{
cout << "\n";
}
#endif
}
}
void print_solutions(ostream& os, bool first)
{
for (auto const& s : sol_list)
{
for (int id : s)
{
if (!id) { break; }
os << input[id].name << " ";
assert(apply(id));
}
os << "\t[";
for (int i = 0; i < 4; ++i)
{
if (i) { os << "\t"; }
os << stats[i];
}
os << "]\n";
for (int id : s)
{
if (!id) { break; }
cancel(id);
}
if (first) { break; }
}
}
int score()
{
return stats[0] + stats[1] + stats[2] + stats[3];
}
int main()
{
sol_list.reserve(1024 * 1024);
sol_list.emplace_back();
best_score = score();
optimize();
// ofstream os("out.txt");
// print_solutions(os, false);
print_solutions(cout, true);
}
I2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnN0cmVhbT4KI2luY2x1ZGUgPHNldD4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGNhc3NlcnQ+CiNpbmNsdWRlIDxmdW5jdGlvbmFsPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKI2RlZmluZSBQUklOVF9QUk9HUkVTUwoKc3RydWN0IGRydWdfaW5mb190CnsKCWNoYXIgbmFtZVs2NF07CglpbnQgcmVxdWlyZTsKCWludCBibG9ja1syXTsKCWludCBlZmZlY3RbNF07Cn07Cgpjb25zdCBkcnVnX2luZm9fdCBpbnB1dFtdID0KewoJLyogaWQgICAgICBuYW1lICAgICAgICAgIHJlcXVpcmUgIGJsb2NrICAgICAgZWZmZWN0ICAgICAgICAgICAgICovCgkvKiAgMCAqLyB7IjxudWxsPiIsICAgICAgMCwgICAgICAgezAsICAwfSwgICB7KzAsICArMCwgICswLCAgKzAgfX0sCgkvKiAgMSAqLyB7IkFNUEVBIiwgICAgICAgMCwgICAgICAgezEzLCAwfSwgICB7KzE0ICArNywgICsxNSAgKzggfX0sCgkvKiAgMiAqLyB7IkJNQSIsICAgICAgICAgMCwgICAgICAgezE0LCAyMn0sICB7KzExLCArMTUsICsxMCwgKzE2fX0sCgkvKiAgMyAqLyB7IkRYQU1QRUEiLCAgICAgMCwgICAgICAgezEwLCAyM30sICB7KzgsICArNywgICsxMSwgKzExfX0sCgkvKiAgNCAqLyB7IlRTVCIsICAgICAgICAgMCwgICAgICAgezE3LCAwfSwgICB7KzcsICArMTMsICsxNSwgKzkgfX0sCgkvKiAgNSAqLyB7IkRIRUEiLCAgICAgICAgMiwgICAgICAgezE1LCAwfSwgICB7KzEzLCArMTIsICs5LCAgKzE5fX0sCgkvKiAgNiAqLyB7IlRIRyIsICAgICAgICAgMCwgICAgICAgezksICAyMH0sICB7KzE3LCArMTcsICsxNCwgKzggfX0sCgkvKiAgNyAqLyB7ImFuYWRyb2wiLCAgICAgNCwgICAgICAgezI0LCAwfSwgICB7KzE3LCArMTQsICsxMSwgKzE0fX0sCgkvKiAgOCAqLyB7IkVQTyIsICAgICAgICAgMSwgICAgICAgezYsICAwfSwgICB7KzEzLCArMCwgICswLCAgLTIgfX0sCgkvKiAgOSAqLyB7ImFyZ294aW4iLCAgICAgOCwgICAgICAgezE1LCAwfSwgICB7KzEwLCAtMSwgICswLCAgKzAgfX0sCgkvKiAxMCAqLyB7ImF0b21veGV0aW4iLCAgOSwgICAgICAgezQsICAxOX0sICB7KzE3LCArMCwgICswLCAgLTQgfX0sCgkvKiAxMSAqLyB7ImJvbGFzdGVyb24iLCAgMCwgICAgICAgezE2LCAxOX0sICB7LTEsICArMTEsICswLCAgLTEgfX0sCgkvKiAxMiAqLyB7ImJvbGFuZGlvbCIsICAgMTEsICAgICAgezE4LCAwfSwgICB7LTIsICArOCwgICsxLCAgLTMgfX0sCgkvKiAxMyAqLyB7ImNhbHVzdGVyb24iLCAgMTIsICAgICAgezIxLCAwfSwgICB7KzAsICArMTAsICswLCAgLTIgfX0sCgkvKiAxNCAqLyB7ImRhbmFzb2wiLCAgICAgMywgICAgICAgezE4LCAwfSwgICB7LTIsICArMCwgICsxNSwgKzIgfX0sCgkvKiAxNSAqLyB7ImVzaWNsZW4iLCAgICAgMTQsICAgICAgezUsICAwfSwgICB7LTEsICArMiwgICsxMCwgKzMgfX0sCgkvKiAxNiAqLyB7InN0YW5vc29sb2wiLCAgMTUsICAgICAgezIzLCAwfSwgICB7KzAsICArMCwgICs5LCAgKzUgfX0sCgkvKiAxNyAqLyB7ImdvbmFkb3JlbGluIiwgMCwgICAgICAgezcsICAwfSwgICB7KzIsICArMSwgIC00LCAgKzE2fX0sCgkvKiAxOCAqLyB7IkZHRiIsICAgICAgICAgMTcsICAgICAgezE2LCAyMH0sICB7LTUsICArMSwgICszLCAgKzggfX0sCgkvKiAxOSAqLyB7ImZvcm1vdGVyb2wiLCAgMTgsICAgICAgezIyLCAwfSwgICB7KzIsICArMCwgICsyLCAgKzE0fX0sCgkvKiAyMCAqLyB7InJhbG94aXBoZW4iLCAgOSwgICAgICAgezUsICAwfSwgICB7KzAsICArMjEsIC0xNSwgLTEwfX0sCgkvKiAyMSAqLyB7ImN5Y2xvcGhlbmlsIiwgMTIsICAgICAgezcsICAwfSwgICB7KzE4LCAtMTksICsyOSwgKzIwfX0sCgkvKiAyMiAqLyB7IkFNUEsiLCAgICAgICAgMjAsICAgICAgezIsICAwfSwgICB7KzIyLCArMCwgIC0xMCwgKzMyfX0sCgkvKiAyMyAqLyB7ImFsYnVtaW4iLCAgICAgMjIsICAgICAgezQsICAwfSwgICB7LTEwLCArMjQsICszMCwgKzYgfX0sCgkvKiAyNCAqLyB7Im1hbm5pdG9sIiwgICAgMTQsICAgICAgezEwLCAwfSwgICB7KzM4LCArMjQsICswLCAgLTEwfX0sCgkvKiAyNSAqLyB7IklHRi0xIiwgICAgICAgMjMsICAgICAgezE5LCAwfSwgICB7LTEwLCArMjEsICsyOCwgKzMxfX0sCn07CmNvbnN0IGludCBOID0gc2l6ZW9mKGlucHV0KSAvIHNpemVvZihkcnVnX2luZm9fdCk7Cgp1c2luZyBzb2x1dGlvbl90ID0gYXJyYXk8aW50LCBOPjsKCmludCBzdGF0c1s0XTsKc2hvcnQgYmxvY2tlZFtOXTsKYm9vbCB1c2VkW05dID0ge3RydWV9Owp2ZWN0b3I8aW50PiBjdXI7CnZlY3Rvcjxzb2x1dGlvbl90PiBzb2xfbGlzdDsKaW50IGJlc3Rfc2NvcmU7CgoKYm9vbCBhcHBseShpbnQgaWQpCnsKCWF1dG8gY29uc3QmIGQgPSBpbnB1dFtpZF07CgoJaWYgKHVzZWRbaWRdIHx8IGJsb2NrZWRbaWRdIHx8ICF1c2VkW2QucmVxdWlyZV0pIHsgcmV0dXJuIGZhbHNlOyB9CgoJdXNlZFtpZF0gPSB0cnVlOwoJKytibG9ja2VkW2QuYmxvY2tbMF1dOwoJKytibG9ja2VkW2QuYmxvY2tbMV1dOwoKCWZvciAoaW50IGkgPSAwOyBpIDwgNDsgKytpKQoJewoJCXN0YXRzW2ldICs9IGQuZWZmZWN0W2ldOwoJfQoKCWN1ci5wdXNoX2JhY2soaWQpOwoKCXJldHVybiB0cnVlOwp9Cgp2b2lkIGNhbmNlbChpbnQgaWQpCnsKCWF1dG8gY29uc3QmIGQgPSBpbnB1dFtpZF07CgoJY3VyLnBvcF9iYWNrKCk7CgoJZm9yIChpbnQgaSA9IDA7IGkgPCA0OyArK2kpCgl7CgkJc3RhdHNbaV0gLT0gZC5lZmZlY3RbaV07Cgl9CgoJLS1ibG9ja2VkW2QuYmxvY2tbMV1dOwoJLS1ibG9ja2VkW2QuYmxvY2tbMF1dOwoJdXNlZFtpZF0gPSBmYWxzZTsKfQoKaW50IHNjb3JlKCk7CnZvaWQgb3B0aW1pemUoKQp7CglpbnQgcyA9IHNjb3JlKCk7CglpZiAocyA+IGJlc3Rfc2NvcmUpCiAgICB7CiAgICAgICAgc29sX2xpc3QuY2xlYXIoKTsKICAgIH0KCWlmIChzID49IGJlc3Rfc2NvcmUpCgl7CgkJc29sX2xpc3QuZW1wbGFjZV9iYWNrKCk7CgkJY29weShjdXIuYmVnaW4oKSwgY3VyLmVuZCgpLCBzb2xfbGlzdC5iYWNrKCkuYmVnaW4oKSk7CgkJYmVzdF9zY29yZSA9IHM7Cgl9CgoJZm9yIChpbnQgaWQgPSAxOyBpZCA8IE47ICsraWQpCgl7CiNpZmRlZiBQUklOVF9QUk9HUkVTUwoJICAgIGlmIChjdXIuZW1wdHkoKSkKICAgICAgICB7CiAgICAgICAgICAgIGNvdXQgPDwgaWQgPDwgIi8iIDw8IChOIC0gMSk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGN1ci5zaXplKCkgPT0gMSkKICAgICAgICB7CiAgICAgICAgICAgIGNvdXQgPDwgIi4iOwogICAgICAgIH0KI2VuZGlmCgoJCWlmIChhcHBseShpZCkpCgkJewoJCQlvcHRpbWl6ZSgpOwoJCQljYW5jZWwoaWQpOwoJCX0KCiNpZmRlZiBQUklOVF9QUk9HUkVTUwoJCWlmIChjdXIuZW1wdHkoKSkKICAgICAgICB7CiAgICAgICAgICAgIGNvdXQgPDwgIlxuIjsKICAgICAgICB9CiNlbmRpZgoJfQp9Cgp2b2lkIHByaW50X3NvbHV0aW9ucyhvc3RyZWFtJiBvcywgYm9vbCBmaXJzdCkKewogICAgZm9yIChhdXRvIGNvbnN0JiBzIDogc29sX2xpc3QpCgl7CgkJZm9yIChpbnQgaWQgOiBzKQoJCXsKCQkgICAgaWYgKCFpZCkgeyBicmVhazsgfQoJCQlvcyA8PCBpbnB1dFtpZF0ubmFtZSA8PCAiICI7CgkJCWFzc2VydChhcHBseShpZCkpOwoJCX0KCgkJb3MgPDwgIlx0WyI7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCA0OyArK2kpCgkJewoJCQlpZiAoaSkgeyBvcyA8PCAiXHQiOyB9CgkJCW9zIDw8IHN0YXRzW2ldOwoJCX0KCQlvcyA8PCAiXVxuIjsKCgkJZm9yIChpbnQgaWQgOiBzKQoJCXsKCQkgICAgaWYgKCFpZCkgeyBicmVhazsgfQoJCQljYW5jZWwoaWQpOwoJCX0KCgkJaWYgKGZpcnN0KSB7IGJyZWFrOyB9Cgl9Cn0KCgppbnQgc2NvcmUoKQp7CglyZXR1cm4gc3RhdHNbMF0gKyBzdGF0c1sxXSArIHN0YXRzWzJdICsgc3RhdHNbM107Cn0KCmludCBtYWluKCkKewogICAgc29sX2xpc3QucmVzZXJ2ZSgxMDI0ICogMTAyNCk7Cglzb2xfbGlzdC5lbXBsYWNlX2JhY2soKTsKCWJlc3Rfc2NvcmUgPSBzY29yZSgpOwoKCW9wdGltaXplKCk7CgovLwlvZnN0cmVhbSBvcygib3V0LnR4dCIpOwovLwlwcmludF9zb2x1dGlvbnMob3MsIGZhbHNlKTsKCglwcmludF9zb2x1dGlvbnMoY291dCwgdHJ1ZSk7Cn0K