// PA2026, @mjm, r2b-sto
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
using namespace std;
using lol = long long;
int nextInt() { int n; scanf("%d", &n); return n; }
lol nextLol() { lol n; scanf("%lld", &n); return n; }
inline lol myMax(lol a, lol b) { return a >= b ? a : b; }
inline int myMin(int a, int b) { return a <= b ? a : b; }
int main() {
int n = nextInt();
int m = nextInt();
int k = nextInt();
vector<vector<lol>> v(n, vector<lol>(m));
vector<int> bad; // numbers of stacks with <= relation
priority_queue<lol> good; // all items from stacks with >= relation
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j)
v[i][j] = nextLol();
if (v[i][0] >= v[i].back()) {
for (int j = 0; j < m; ++j)
good.push(v[i][j]);
} else {
bad.push_back(i);
}
}
vector<lol> cur(1, 0);
for (int i = 0; i < bad.size(); ++i) {
int id = bad[i];
int nexSize = cur.size() + m;
if (nexSize > k)
nexSize = k + 1;
vector<lol> nex(cur);
nex.resize(nexSize, 0);
lol sum = 0;
for (int j=0; j<m; ++j) {
sum += v[id][j];
// x + j + 1 < nexSize
// x < nexSize - j - 1
int xEn = myMin(cur.size(), nexSize - j - 1);
for (int x = 0; x < xEn; ++x) {
lol& nn = nex[x + j + 1];
nn = myMax(nn, cur[x] + sum);
}
}
swap(cur, nex);
}
lol goodSum = 0;
int badMaxK = cur.size() - 1;
if (badMaxK < k) {
int cnt = k - badMaxK;
for (int i = 0; i < cnt; ++i) {
goodSum += good.top();
good.pop();
}
}
lol res = 0;
for (int badK = cur.size() - 1; badK >= 0; --badK) {
res = myMax(res, cur[badK] + goodSum);
if (good.empty())
break;
goodSum += good.top();
good.pop();
}
printf("%lld\n", res);
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 | // PA2026, @mjm, r2b-sto #include <cstdio> #include <cmath> #include <vector> #include <queue> using namespace std; using lol = long long; int nextInt() { int n; scanf("%d", &n); return n; } lol nextLol() { lol n; scanf("%lld", &n); return n; } inline lol myMax(lol a, lol b) { return a >= b ? a : b; } inline int myMin(int a, int b) { return a <= b ? a : b; } int main() { int n = nextInt(); int m = nextInt(); int k = nextInt(); vector<vector<lol>> v(n, vector<lol>(m)); vector<int> bad; // numbers of stacks with <= relation priority_queue<lol> good; // all items from stacks with >= relation for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) v[i][j] = nextLol(); if (v[i][0] >= v[i].back()) { for (int j = 0; j < m; ++j) good.push(v[i][j]); } else { bad.push_back(i); } } vector<lol> cur(1, 0); for (int i = 0; i < bad.size(); ++i) { int id = bad[i]; int nexSize = cur.size() + m; if (nexSize > k) nexSize = k + 1; vector<lol> nex(cur); nex.resize(nexSize, 0); lol sum = 0; for (int j=0; j<m; ++j) { sum += v[id][j]; // x + j + 1 < nexSize // x < nexSize - j - 1 int xEn = myMin(cur.size(), nexSize - j - 1); for (int x = 0; x < xEn; ++x) { lol& nn = nex[x + j + 1]; nn = myMax(nn, cur[x] + sum); } } swap(cur, nex); } lol goodSum = 0; int badMaxK = cur.size() - 1; if (badMaxK < k) { int cnt = k - badMaxK; for (int i = 0; i < cnt; ++i) { goodSum += good.top(); good.pop(); } } lol res = 0; for (int badK = cur.size() - 1; badK >= 0; --badK) { res = myMax(res, cur[badK] + goodSum); if (good.empty()) break; goodSum += good.top(); good.pop(); } printf("%lld\n", res); return 0; } |
English