Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio>
- #include <iostream>
- #include <vector>
- #include <algorithm>
- using namespace std;
- struct Obj {
- int cost, size;
- int id;
- Obj(int cost=0, int size=0, int id=-1)
- {
- this->cost = cost;
- this->size = size;
- this->id = id + 1;
- }
- };
- struct Comp {
- bool operator()(const Obj& a, const Obj& b) const
- {
- /// Decreasing order.
- return a.size > b.size;
- }
- };
- typedef unsigned long long ull_t;
- typedef vector<Obj> vO_t;
- typedef vector<pair<int, int> > vp_t;
- typedef vector<int> vi_t;
- int n, m;
- vO_t shoe, client;
- ull_t maxProfit;
- ull_t* dp[3];
- vp_t soldIndex;
- vector<vi_t > adjList;
- vi_t picked;
- vector<bool> seen;
- ull_t max_state(int state)
- {
- return max(dp[0][state], max(dp[1][state], dp[2][state]));
- }
- void show_dp(int state)
- {
- /// Debugging.
- for (int i = 0; i < 3; ++i) {
- cerr << dp[i][state] << " ";
- }
- cerr << endl;
- }
- void solve()
- {
- // generate first phase
- Obj item = client[0];
- int lastSize = item.size;
- dp[0][0] = dp[1][0] = dp[2][0] = 0;
- vO_t::iterator src = lower_bound(shoe.begin(), shoe.end(), item, Comp());
- if (src->size == item.size && src->cost <= item.cost) {
- dp[1][0] = src->cost;
- }
- ++item.size;
- src = lower_bound(shoe.begin(), shoe.end(), item, Comp());
- if (src->size == item.size && src->cost <= item.cost) {
- dp[2][0] = src->cost;
- }
- //show_dp(0);
- ////////////////////////////
- for (int i = 1; i < m; ++i) {
- // init state
- ull_t maxBefore = max_state(i - 1);
- dp[0][i] = dp[1][i] = dp[2][i] = maxBefore;
- // extract client and find a matching shoe for him
- item = client[i];
- bool low = lastSize - item.size; // 0-(client with same size)
- int tmpLastSize = lastSize;
- lastSize = item.size;
- // for l and l+1
- for (; item.size <= lastSize + 1; ++item.size) {
- src = lower_bound(shoe.begin(), shoe.end(), item, Comp());
- // check if he has enough money
- if (src->size == item.size && src->cost <= item.cost) {
- if (low) {
- if (item.size == lastSize) {
- dp[1][i] += src->cost;
- } else if (item.size == tmpLastSize) {
- //dp[2][i] += src->cost + dp[2][i - 1] - dp[0][i - 1]); busit
- } else {
- dp[2][i] += src->cost;
- }
- } else {
- if (item.size == lastSize) {
- //dp[1][i] = src->cost + si mai busit
- } else {
- //dp[2][i] = ................. /// pula-n pizda ;]
- }
- }
- }
- }
- }
- maxProfit = max_state(m - 1);
- }
- void go_back()
- {
- ull_t crtProfit = maxProfit;
- for (int i = m - 1; i >= 0; --i) {
- if (crtProfit == dp[0][i]) continue;
- Obj item = client[i];
- if (crtProfit == dp[2][i]) ++item.size;
- vO_t::iterator src = lower_bound(shoe.begin(), shoe.end(), item, Comp());
- soldIndex.push_back(make_pair(item.id, src->id));
- crtProfit -= src->cost;
- }
- }
- void test()
- {
- for (int i = 0; i < n; ++i) {
- Obj tmp = shoe[i];
- cerr << tmp.id << " " << tmp.cost << " " << tmp.size << endl;
- }
- for (int i = 0; i < m; ++i) {
- Obj tmp = client[i];
- cerr << tmp.id << " " << tmp.cost << " " << tmp.size << endl;
- }
- cerr << "=============\n";
- for (int i = m - 1; i >= 0; --i) {
- Obj item = client[i];
- ++item.size;
- vO_t::iterator src = lower_bound(shoe.begin(), shoe.end(), item, Comp());
- cerr << "For client with id: " << item.id << " money: " << item.cost << " and size: " << item.size;
- cerr << " shoe with id: " << src->id << " cost: " << src->cost << " and size: " << src->size << endl;
- }
- }
- void solve2()
- {
- for (int i = 0; i < m; ++i) {
- Obj cl = client[i];
- //cerr << "Client: " << cl.id << " Marime: " << cl.size << endl;
- int clSize = cl.size;
- ++cl.size;
- vO_t::iterator it = lower_bound(shoe.begin(), shoe.end(), cl, Comp());
- //cerr << "Adidas: " << it->id << " Marime: " << it->size << endl << endl;
- for (; it != shoe.end() && (it->size == clSize || it->size == clSize + 1); it++) {
- //cerr << cl.id << " " << it->id << endl;
- if (cl.cost >= it->cost) adjList[it->id].push_back(cl.id);
- }
- }
- }
- bool pick(int id)
- {
- for (int i = 0; i < adjList[id].size(); ++i) {
- int clid = adjList[id][i];
- if (seen[clid]) continue;
- seen[clid] = true;
- if (!picked[clid] || pick(picked[clid])) {
- picked[clid] = id;
- return true;
- }
- }
- return false;
- }
- void go_back2()
- {
- for (int i = 0; i < n; ++i) {
- seen.clear();
- if (pick(shoe[i].id)) {
- ++picked[0];
- maxProfit += shoe[i].cost;
- }
- }
- for (int i = 1; i <= m; ++i) {
- if (picked[i]) soldIndex.push_back(make_pair(i, picked[i]));
- }
- }
- void test2()
- {
- for (int i = 0; i < adjList.size(); ++i) {
- for (int j = 0; j < adjList[i].size(); ++j) {
- cerr << i << " " << j << endl;
- }
- }
- }
- int main()
- {
- //freopen("D.in", "r", stdin);
- cin >> n;
- shoe.resize(n);
- adjList.resize(n + 1);
- for (int i = 0; i < n; ++i) {
- int cost, size;
- cin >> cost >> size;
- shoe[i] = Obj(cost, size, i);
- }
- cin >> m;
- //for (int i = 0; i < 3; ++i) dp[i] = new ull_t[m];
- client.resize(m);
- seen.resize(m);
- picked.resize(m + 1);
- for (int i = 0; i < m; ++i) {
- int money, size;
- cin >> money >> size;
- client[i] = Obj(money, size, i);
- }
- sort(shoe.begin(), shoe.end(), Comp());
- sort(client.begin(), client.end(), Comp());
- //test();
- //solve();
- solve2();
- //test2();
- go_back2();
- cout << maxProfit << '\n';
- //go_back();
- cout << soldIndex.size() << '\n';
- for (int i = 0; i < soldIndex.size(); ++i) {
- cout << soldIndex[i].first << ' ' << soldIndex[i].second << '\n';
- }
- //for (int i = 0; i < 3; ++i) delete[] dp[i];
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement