#include #include #include #include using namespace std; const int bits[10] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200}; void normalize(map, int> &overlay, int n) { for (int i = n-1; i >= 0; i--) { for (map, int>::iterator p = overlay.begin(); p != overlay.end(); p++) { if (p->first.size() == i) { for (map, int>::iterator q = overlay.begin(); q != overlay.end(); q++) { if (q->first.size() < i) { if (includes(p->first.begin(), p->first.end(), q->first.begin(), q->first.end())) { if ((p->first.size() - q->first.size()) % 2 == 0) { q->second -= p->second; } else { q->second += p->second; } } } } } } } } int add(const set &oldset, int newtower, map, int> &overlay) { int difference = 0; for (int i = 0; i < bits[oldset.size()]; i++) { set candidate; set::iterator p = oldset.begin(); for (int j = 0; p != oldset.end(); j++) { if (i & bits[j]) { candidate.insert(*p); } candidate.insert(newtower); if (candidate.size() % 2 == 0) { difference -= overlay[candidate]; } else { difference += overlay[candidate]; } p++; } } return difference; } int main() { int Icase; int n; /* Towers planned */ int r; /* Actually */ int total[21]; int m; /* Number of Overlay Areas */ map< set, int > chosen[2]; for (Icase = 1; ; Icase++) { map< set, int > overlay; set max_group; int max_customer = 0; cin >> n >> r; if (n == 0 && r == 0) { break; } for (int i = 1; i <= n; i++) { cin >> total[i]; } cin >> m; for (int i = 0; i < m; i++) { int t, num; set s; cin >> t; for (int j = 0; j < t; j++) { int x; cin >> x; s.insert(x); } cin >> num; overlay[s] = num; } normalize(overlay, n); chosen[0].clear(); chosen[1].clear(); set tmp; chosen[0][tmp] = 0; for (int n_overlay = 0; n_overlay <= r; n_overlay++) { for (map, int>::iterator p = chosen[0].begin(); p != chosen[0].end(); p++) { for (int i = 1; i <= n; i++) { if (p->first.find(i) == p->first.end()) { set newset = p->first; newset.insert(i); chosen[1][newset] = chosen[0][p->first] + total[i] + add(p->first, i, overlay); if (n_overlay == r-1 && max_customer < chosen[1][newset]) { max_group = newset; max_customer = chosen[1][newset]; } } } } chosen[0] = chosen[1]; chosen[1].clear(); } cout << "Case Number " << Icase << endl; cout << "Number of Customers: " << max_customer << endl; cout << "Locations recommended:"; for (set::iterator p = max_group.begin(); p != max_group.end(); p++) { cout << " " << *p; } cout << endl << endl; } return 0; }