#include <bits/stdc++.h>
using namespace std;
using ll = long long;
vector<ll> solveInc(vector<vector<ll>>& pref_sum, int j) {
sort(pref_sum.begin(), pref_sum.end(), [j](const vector<ll>& a, const vector<ll>& b) {
if (a.back() != b.back())
return a.back() > b.back();
return a[j] < b[j];
});
vector<ll> min_suffix;
ll sum = 0;
for (long unsigned int i = 0; i < pref_sum.size(); i++) {
auto &v = pref_sum[i];
sum += v.back();
if (i == 0)
min_suffix.push_back(v.back() - v[j - 1]);
else
min_suffix.push_back(min(min_suffix.back(), v.back() - v[j - 1]));
}
int n = pref_sum.size();
vector<ll> res(n, 0);
ll max_prefix = 0;
for (int i = n - 1; i >= 0; --i) {
max_prefix = max(max_prefix, pref_sum[i][j - 1]);
res[i] = max(sum - min_suffix[i], sum - pref_sum[i].back() + max_prefix);
sum -= pref_sum[i].back();
}
return res;
}
vector<ll> solveInc(vector<vector<ll>>& grid) {
int n = grid.size();
if (n == 0) {
return vector<ll>{0};
}
int m = grid[0].size();
vector<vector<ll>> pref_sum;
pref_sum.assign(n, vector<ll>(m, 0));
for (int i = 0; i < n; ++i) {
pref_sum[i][0] = grid[i][0];
for (int j = 1; j < m; ++j) {
pref_sum[i][j] = pref_sum[i][j - 1] + (ll) grid[i][j];
}
}
vector<ll> res(m * n + 1, 0);
for (int j = 1; j <= m; ++j) {
vector<ll> nToSum = solveInc(pref_sum, j);
for (long unsigned int i = 0; i < nToSum.size(); i++) {
res[m * i + j] = nToSum[i];
}
}
return res;
}
vector<ll> solveDec(vector<vector<ll>>& grid) {
int m = grid[0].size(), n = grid.size();
auto cmp = [&grid](pair<int,int> a, pair<int,int> b) {
return grid[a.first][a.second] < grid[b.first][b.second]; // większe second na górze
};
priority_queue<pair<int,int>, vector<pair<int,int>>, decltype(cmp)> pq(cmp);
vector<ll> res(1, 0);
for (int i = 0; i < n; ++i) {
pq.push({i, 0});
}
while (!pq.empty()) {
pair<int,int> top = pq.top();
pq.pop();
res.push_back(res.back() + grid[top.first][top.second]);
if (top.second + 1 < m) {
pq.push({top.first, top.second + 1});
}
}
return res;
}
vector<vector<ll>> decr;
vector<vector<ll>> incr;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m, k;
cin >> n >> m >> k;
for (int i = 0; i < n; ++i) {
vector<ll> curr;
ll a;
for (int j = 0; j < m; ++j) {
cin >> a;
curr.push_back(a);
}
if (curr.front() < curr.back()) {
incr.push_back(curr);
} else {
decr.push_back(curr);
}
}
vector<ll> kToSumInc = solveInc(incr);
vector<ll> kToSumDec = solveDec(decr);
ll res = 0;
for (long unsigned int i = (long unsigned int) max(0, k - (int) kToSumInc.size() + 1); i <= min((long unsigned int) k, kToSumDec.size() - 1); ++i) {
res = max(res, kToSumDec[i] + kToSumInc[k - i]);
}
cout << res << 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 | #include <bits/stdc++.h> using namespace std; using ll = long long; vector<ll> solveInc(vector<vector<ll>>& pref_sum, int j) { sort(pref_sum.begin(), pref_sum.end(), [j](const vector<ll>& a, const vector<ll>& b) { if (a.back() != b.back()) return a.back() > b.back(); return a[j] < b[j]; }); vector<ll> min_suffix; ll sum = 0; for (long unsigned int i = 0; i < pref_sum.size(); i++) { auto &v = pref_sum[i]; sum += v.back(); if (i == 0) min_suffix.push_back(v.back() - v[j - 1]); else min_suffix.push_back(min(min_suffix.back(), v.back() - v[j - 1])); } int n = pref_sum.size(); vector<ll> res(n, 0); ll max_prefix = 0; for (int i = n - 1; i >= 0; --i) { max_prefix = max(max_prefix, pref_sum[i][j - 1]); res[i] = max(sum - min_suffix[i], sum - pref_sum[i].back() + max_prefix); sum -= pref_sum[i].back(); } return res; } vector<ll> solveInc(vector<vector<ll>>& grid) { int n = grid.size(); if (n == 0) { return vector<ll>{0}; } int m = grid[0].size(); vector<vector<ll>> pref_sum; pref_sum.assign(n, vector<ll>(m, 0)); for (int i = 0; i < n; ++i) { pref_sum[i][0] = grid[i][0]; for (int j = 1; j < m; ++j) { pref_sum[i][j] = pref_sum[i][j - 1] + (ll) grid[i][j]; } } vector<ll> res(m * n + 1, 0); for (int j = 1; j <= m; ++j) { vector<ll> nToSum = solveInc(pref_sum, j); for (long unsigned int i = 0; i < nToSum.size(); i++) { res[m * i + j] = nToSum[i]; } } return res; } vector<ll> solveDec(vector<vector<ll>>& grid) { int m = grid[0].size(), n = grid.size(); auto cmp = [&grid](pair<int,int> a, pair<int,int> b) { return grid[a.first][a.second] < grid[b.first][b.second]; // większe second na górze }; priority_queue<pair<int,int>, vector<pair<int,int>>, decltype(cmp)> pq(cmp); vector<ll> res(1, 0); for (int i = 0; i < n; ++i) { pq.push({i, 0}); } while (!pq.empty()) { pair<int,int> top = pq.top(); pq.pop(); res.push_back(res.back() + grid[top.first][top.second]); if (top.second + 1 < m) { pq.push({top.first, top.second + 1}); } } return res; } vector<vector<ll>> decr; vector<vector<ll>> incr; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m, k; cin >> n >> m >> k; for (int i = 0; i < n; ++i) { vector<ll> curr; ll a; for (int j = 0; j < m; ++j) { cin >> a; curr.push_back(a); } if (curr.front() < curr.back()) { incr.push_back(curr); } else { decr.push_back(curr); } } vector<ll> kToSumInc = solveInc(incr); vector<ll> kToSumDec = solveDec(decr); ll res = 0; for (long unsigned int i = (long unsigned int) max(0, k - (int) kToSumInc.size() + 1); i <= min((long unsigned int) k, kToSumDec.size() - 1); ++i) { res = max(res, kToSumDec[i] + kToSumInc[k - i]); } cout << res << endl; return 0; } |
English