#include <bits/stdc++.h>
using namespace std;
const int64_t INF = 1e18;
int main () {
ios_base::sync_with_stdio(0); cin.tie(0);
int n, m, k;
cin >> n >> m >> k;
vector<int64_t> pile;
vector<pair<int64_t, vector<int64_t>>> A;
for (int i = 0; i < n; i++) {
vector<int64_t> a(m);
for (auto& x: a) cin >> x;
if (is_sorted(a.begin(), a.end(), greater<int64_t>())) {
for (auto x: a) pile.push_back(x);
continue;
}
A.emplace_back(accumulate(a.begin(), a.end(), 0LL), a);
}
sort(pile.begin(), pile.end(), greater<int64_t>());
sort(A.begin(), A.end(), [&] (const auto& a, const auto& b) {
return a.first > b.first;
});
const int sz = A.size();
vector<int64_t> group_pref(sz+1);
for (int i = 0; i < sz; i++) {
group_pref[i+1] = group_pref[i] + A[i].first;
}
vector<int64_t> res_sum(sz);
vector<int64_t> best(sz*m+1);
vector<int64_t> prefmax(sz+1), suffmax(sz+1);
prefmax[0] = -INF;
for (int r = 0; r < m; r++) {
for (int i = sz-1; i >= 0; i--) {
suffmax[i] = max(suffmax[i+1], res_sum[i]);
}
for (int i = 0; i < sz; i++) {
prefmax[i+1] = max(prefmax[i], res_sum[i] - A[i].first);
}
for (int c = 0; c <= sz; c++) {
int taken = c*m+r;
if (taken > sz*m) continue;
// top c piles, maximum res_sum of remaining sz-c
best[taken] = max(best[taken], group_pref[c] + suffmax[c]);
// or top c+1 piles + maximum (res_sum - sum) of first c+1
if (c != sz) best[taken] = max(best[taken], group_pref[c+1] + prefmax[c+1]);
}
for (int i = 0; i < sz; i++) {
res_sum[i] += A[i].second[r];
}
}
int64_t ans = 0;
int64_t pile_sum = 0;
for (int i = 0; i <= (int)pile.size() && i <= k; i++) {
if (k-i < (int)best.size()) ans = max(ans, pile_sum + best[k-i]);
if (i < (int)pile.size()) pile_sum += pile[i];
}
cout << ans << '\n';
}
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 | #include <bits/stdc++.h> using namespace std; const int64_t INF = 1e18; int main () { ios_base::sync_with_stdio(0); cin.tie(0); int n, m, k; cin >> n >> m >> k; vector<int64_t> pile; vector<pair<int64_t, vector<int64_t>>> A; for (int i = 0; i < n; i++) { vector<int64_t> a(m); for (auto& x: a) cin >> x; if (is_sorted(a.begin(), a.end(), greater<int64_t>())) { for (auto x: a) pile.push_back(x); continue; } A.emplace_back(accumulate(a.begin(), a.end(), 0LL), a); } sort(pile.begin(), pile.end(), greater<int64_t>()); sort(A.begin(), A.end(), [&] (const auto& a, const auto& b) { return a.first > b.first; }); const int sz = A.size(); vector<int64_t> group_pref(sz+1); for (int i = 0; i < sz; i++) { group_pref[i+1] = group_pref[i] + A[i].first; } vector<int64_t> res_sum(sz); vector<int64_t> best(sz*m+1); vector<int64_t> prefmax(sz+1), suffmax(sz+1); prefmax[0] = -INF; for (int r = 0; r < m; r++) { for (int i = sz-1; i >= 0; i--) { suffmax[i] = max(suffmax[i+1], res_sum[i]); } for (int i = 0; i < sz; i++) { prefmax[i+1] = max(prefmax[i], res_sum[i] - A[i].first); } for (int c = 0; c <= sz; c++) { int taken = c*m+r; if (taken > sz*m) continue; // top c piles, maximum res_sum of remaining sz-c best[taken] = max(best[taken], group_pref[c] + suffmax[c]); // or top c+1 piles + maximum (res_sum - sum) of first c+1 if (c != sz) best[taken] = max(best[taken], group_pref[c+1] + prefmax[c+1]); } for (int i = 0; i < sz; i++) { res_sum[i] += A[i].second[r]; } } int64_t ans = 0; int64_t pile_sum = 0; for (int i = 0; i <= (int)pile.size() && i <= k; i++) { if (k-i < (int)best.size()) ans = max(ans, pile_sum + best[k-i]); if (i < (int)pile.size()) pile_sum += pile[i]; } cout << ans << '\n'; } |
English