Submission #656038

#TimeUsernameProblemLanguageResultExecution timeMemory
656038600MihneaOlympiads (BOI19_olympiads)C++17
100 / 100
27 ms1852 KiB
#include <bits/stdc++.h>

using namespace std;

const int N = 500 + 7;
const int K = 7 + 7;
int n;
int k;
int c;
int a[N][K];
vector<int> inds[K];

set<long long> seen;
priority_queue<pair<int, long long>> q;
set<long long> Hashes;

long long get_hash(vector<int> positions) { /// bijection
  long long h = 0;
  for (int i = 0; i < k; i++) {
    h = h * N + positions[i];
  }
  return h;
}

vector<int> get_positions(long long Hash) { /// bijection
  vector<int> positions(k);
  for (int i = k - 1; i >= 0; i--) {
    positions[i] = Hash % N;
    Hash /= N;
  }
  return positions;
}

int get_sum(vector<int> positions) {
  int sum = 0;
  for (int i = 0; i < k; i++) {
    sum +=  a[inds[i][positions[i]]][i];
  }
  return sum;
}

vector<int> Fixed;
vector<int> notFixed;

void bkt(vector<int> current, int position, int sum) {
  if ((int) current.size() == k) {
    sort(current.begin(), current.end());
    long long Hash = get_hash(current);
    Hashes.insert(Hash);
    if ((int) Hashes.size() == c) {
      cout << sum << "\n";
      exit(0);
    }
    return;
  }
  if (position == (int) notFixed.size()) {
    return;
  }
  bkt(current, position + 1, sum);
  current.push_back(notFixed[position]);
  bkt(current, position + 1, sum);
}

void add(vector<int> positions) {
  long long Hash = get_hash(positions);
  if (seen.count(Hash)) {
    return;
  }
  seen.insert(Hash);
  int sum = get_sum(positions);
  q.push({sum, Hash});
}

int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);

  cin >> n >> k >> c;
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < k; j++) {
      cin >> a[i][j];
    }
  }
  {
    vector<int> biggest;
    for (int c = 0; c < k; c++) {
      for (int i = 1; i <= n; i++) {
        inds[c].push_back(i);
      }
      sort(inds[c].begin(), inds[c].end(), [&] (int i, int j) {
        return a[i][c] > a[j][c];
      });
      biggest.push_back(0);
    }
    add(biggest);
  }
  while (!q.empty()) {
    long long Hash = q.top().second;
    {
        vector<int> positions = get_positions(Hash);
        int sum = q.top().first;
        set<int> sFixed;
        Fixed.clear();
        notFixed.clear();
        for (int c = 0; c < k; c++) {
          sFixed.insert(inds[c][positions[c]]);
        }
        for (auto &i : sFixed) {
          Fixed.push_back(i);
        }
        for (int i = 1; i <= n; i++) {
          if (!sFixed.count(i)) {
            notFixed.push_back(i);
          }
        }
        bkt(Fixed, 0, sum);
    }
    q.pop();
    vector<int> positions = get_positions(Hash);
    for (int g = 0; g < k; g++) {
      if (positions[g] + 1 < n) {
        vector<int> np = positions;
        np[g]++;
        add(np);
      }
    }
  }
  return 0;
}


/**

**/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...