This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
using ll = long long;
using vi = vector<int>;
using vl = vector<ll>;
void FASTIO() {ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); }
const int MXN = 505;
const int MXK = 7;
int n, k, c;
ll A[MXK][MXN];
ll B[MXK][MXN];
int main() {
FASTIO();
cin >> n >> k >> c;
for(int i = 0; i < n; i++) {
for(int j = 0; j < k; j++) {
cin >> A[j][i]; B[j][i] = A[j][i];
}
}
//cerr << "-------------\n";
for(int i = 0; i < k; i++) sort(B[i], B[i]+n), reverse(B[i], B[i]+n);
// for(int i = 0; i < n; i++) {
// for(int j = 0; j < k; j++) {
// cerr << B[j][i] << " ";
// }
// cerr << "\n";
// }
priority_queue<pair<int, vi>> PQ;
set<vi> visited;
{
int val = 0; for(int i = 0; i < k; i++) val += B[i][0];
visited.insert(vi(k));
PQ.push({val, vi(k)});
}
// how many ways to cover each subset of {0, 1, ..., k-1} using set num of elements
ll dp[2][k+1][1<<k];
while(!PQ.empty() && c > 0) {
int curr_val = PQ.top().F;
vi ids = PQ.top().S; PQ.pop();
// cerr << "-----------\n";
// cerr << curr_val << ", c = " << c << "\n";
// for(int i = 0; i < k; i++) cerr << ids[i] << " ";
// cerr << "\n";
// for(int i = 0; i < k; i++) cerr << B[i][ids[i]] << " ";
// cerr << "\n";
ll cnt = 0; // how many different teams can have maximum equal to B[k][ids[k]] for each k?
// bitmask dp
int from = 0, to = 1;
memset(dp[from], 0, sizeof(dp[from]));
dp[from][0][0] = 1;
for(int i = 0; i < n; i++) {
memset(dp[to], 0, sizeof(dp[to]));
int b_i = 0;
bool bad = false;
for(int j = 0; j < k; j++) {
if(A[j][i] > B[j][ids[j]]) bad = true; // can't take higher value
if(A[j][i] == B[j][ids[j]]) b_i |= 1 << j;
}
if(bad) continue;
for(int b = 0; b < (1<<k); b++) {
int b_to = b|b_i;
for(int u = 1; u <= k; u++) {
dp[to][u][b_to] += dp[from][u-1][b];
}
}
for(int b = 0; b < (1<<k); b++) {
for(int u = 0; u <= k; u++) {
dp[to][u][b] += dp[from][u][b]; // don't take i-th
}
}
swap(from, to);
}
cnt = dp[from][k][(1<<k)-1];
//cerr << cnt << "!\n";
if(c - cnt <= 0) {
cout << curr_val << "\n";
return 0;
}
c -= cnt;
for(int i = 0; i < k; i++) {
vi new_ids = ids;
while(new_ids[i]<n && B[i][ids[i]] == B[i][new_ids[i]]) new_ids[i]++;
if(new_ids[i]+k-1<n) {
int val = 0; for(int j = 0; j < k; j++) val += B[j][new_ids[j]];
if(!visited.count(new_ids)) {
visited.insert(new_ids);
PQ.push({val, new_ids});
}
}
}
}
return 0;
}
/*
5 4 4
7 0 4 9
3 0 8 4
1 1 3 7
5 1 3 4
4 2 2 9
1 1 1
1
*/
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |