#include <iostream>
#include <vector>
#include <utility>
#include <queue>
struct Stack {
std::vector<long long> numbers;
long long sum;
Stack(int n) {
this->numbers = std::vector<long long>(n);
this->sum = 0;
}
};
bool isDescending(const std::vector<long long> &stack) {
if (stack.size() == 1) {
return true;
}
for (int i = 0; i + 1 < stack.size(); i++) {
if (stack[i] < stack[i + 1]) {
return false;
}
}
return true;
}
int main() {
int n, m, k;
std::cin >> n >> m >> k;
std::vector<Stack> ascending, descending;
for (int i = 0; i < n; i++) {
Stack stack(m);
for (int j = 0; j < m; j++) {
std::cin >> stack.numbers[j];
stack.sum += stack.numbers[j];
}
if (isDescending(stack.numbers)) {
descending.push_back(stack);
} else {
ascending.push_back(stack);
}
}
std::priority_queue< std::pair<long long, int> > candidates;
for (int i = 0; i < descending.size(); i++) {
candidates.push({descending[i].numbers[0], i});
}
int desc_count = descending.size() * m;
int asc_count = ascending.size() * m;
std::vector<int> heads(descending.size(), 0);
std::vector<long long> a(descending.size() * m + 1, 0);
long long d = 0;
for (int i = 1; i <= desc_count; i++) {
auto c = candidates.top();
d += c.first;
a[i] = d;
candidates.pop();
if (heads[c.second] + 1 < m) {
heads[c.second]++;
candidates.push({descending[c.second].numbers[heads[c.second]], c.second});
}
}
if (m == 1) {
std::cout << a[k] << std::endl;
return 0;
}
std::sort(ascending.begin(), ascending.end(), [](const Stack& s1, const Stack &s2) {
return s1.sum > s2.sum;
});
std::priority_queue< std::pair<long long, int> > prefixes[m];
for (int i = 0; i < ascending.size(); i++) {
long long sum = 0;
for (int j = 0; j + 1 < m; j++) {
sum += ascending[i].numbers[j];
prefixes[j + 1].push({sum, i});
}
}
int next = -1;
long long result = desc_count >= k ? a[k] : 0;
long long entire = 0;
for (int i = 1; i <= std::min(asc_count, k); i++) {
int pref = i % m;
if (pref == 0) {
next += 1;
entire += ascending[next].sum;
}
if (i + desc_count < k) {
continue;
}
long long v = a[k - i];
if (pref != 0) {
while (prefixes[pref].size() > 0) {
auto p = prefixes[pref].top();
if (p.second > next) {
v += p.first;
break;
} else {
prefixes[pref].pop();
}
}
}
v += entire;
result = std::max(result, v);
}
std::cout << result << std::endl;
return 0;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | #include <iostream> #include <vector> #include <utility> #include <queue> struct Stack { std::vector<long long> numbers; long long sum; Stack(int n) { this->numbers = std::vector<long long>(n); this->sum = 0; } }; bool isDescending(const std::vector<long long> &stack) { if (stack.size() == 1) { return true; } for (int i = 0; i + 1 < stack.size(); i++) { if (stack[i] < stack[i + 1]) { return false; } } return true; } int main() { int n, m, k; std::cin >> n >> m >> k; std::vector<Stack> ascending, descending; for (int i = 0; i < n; i++) { Stack stack(m); for (int j = 0; j < m; j++) { std::cin >> stack.numbers[j]; stack.sum += stack.numbers[j]; } if (isDescending(stack.numbers)) { descending.push_back(stack); } else { ascending.push_back(stack); } } std::priority_queue< std::pair<long long, int> > candidates; for (int i = 0; i < descending.size(); i++) { candidates.push({descending[i].numbers[0], i}); } int desc_count = descending.size() * m; int asc_count = ascending.size() * m; std::vector<int> heads(descending.size(), 0); std::vector<long long> a(descending.size() * m + 1, 0); long long d = 0; for (int i = 1; i <= desc_count; i++) { auto c = candidates.top(); d += c.first; a[i] = d; candidates.pop(); if (heads[c.second] + 1 < m) { heads[c.second]++; candidates.push({descending[c.second].numbers[heads[c.second]], c.second}); } } if (m == 1) { std::cout << a[k] << std::endl; return 0; } std::sort(ascending.begin(), ascending.end(), [](const Stack& s1, const Stack &s2) { return s1.sum > s2.sum; }); std::priority_queue< std::pair<long long, int> > prefixes[m]; for (int i = 0; i < ascending.size(); i++) { long long sum = 0; for (int j = 0; j + 1 < m; j++) { sum += ascending[i].numbers[j]; prefixes[j + 1].push({sum, i}); } } int next = -1; long long result = desc_count >= k ? a[k] : 0; long long entire = 0; for (int i = 1; i <= std::min(asc_count, k); i++) { int pref = i % m; if (pref == 0) { next += 1; entire += ascending[next].sum; } if (i + desc_count < k) { continue; } long long v = a[k - i]; if (pref != 0) { while (prefixes[pref].size() > 0) { auto p = prefixes[pref].top(); if (p.second > next) { v += p.first; break; } else { prefixes[pref].pop(); } } } v += entire; result = std::max(result, v); } std::cout << result << std::endl; return 0; } |
English