#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
constexpr LL INF = 1'000'000'000'000'000'000LL;
struct MyStack {
deque<LL> stack;
deque<LL> pref_sum;
LL sum_query(int l, int r) {
return pref_sum[r] - pref_sum[l];
}
void init_pref() {
pref_sum.resize(stack.size()+1);
pref_sum[0] = 0;
for (int i = 0; i < stack.size(); ++i) {
pref_sum[i+1] = pref_sum[i] + stack[i];
}
}
bool operator<(const MyStack& x) const {
return pref_sum.back() < x.pref_sum.back();
}
};
void solve_asc_mod(vector<MyStack>& stacks, LL rem, LL n, LL m, vector<LL>& res) {
multiset<LL> best_left;
LL minimum = INF;
for (int i = 0; i < n; ++i) {
best_left.insert(stacks[i].sum_query(0, rem));
}
LL all_sum = 0;
for (int i = 0; i < n; ++i) {
LL c1 = all_sum + *best_left.rbegin();
all_sum += stacks[i].sum_query(0, m);
minimum = min(minimum, stacks[i].sum_query(rem, m));
LL c2 = all_sum - minimum;
best_left.erase(best_left.find(stacks[i].sum_query(0, rem)));
int idx = rem + (m*i);
res[rem+(m*i)] = max(c1, c2);
}
if (rem == 0) {
res[n*m] = all_sum;
}
}
vector<LL> solve_asc(vector<deque<LL>>& raw_stacks) {
if (raw_stacks.size() == 0) {
return {0};
}
LL n = raw_stacks.size();
LL m = raw_stacks[0].size();
vector<MyStack> stacks(n);
for (int i = 0; i < n; ++i) {
stacks[i].stack = raw_stacks[i];
stacks[i].init_pref();
}
sort(stacks.rbegin(), stacks.rend());
vector<LL> res((n*m)+1, 0);
for (int i = 0; i < m; ++i) {
solve_asc_mod(stacks, i, n, m, res);
}
return res;
}
vector<LL> solve_desc(vector<deque<LL>>& stacks) {
vector<LL> flat;
for (auto& x : stacks) {
for (auto& y : x) {
flat.push_back(y);
}
}
sort(flat.rbegin(), flat.rend());
vector<LL> res;
res.push_back(0);
for (auto& x : flat) {
res.push_back(res.back() + x);
}
return res;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
LL n, m, k;
cin >> n >> m >> k;
vector<deque<LL>> stacks(n, deque<LL>(m));
deque<bool> is_asc(n, false);
vector<LL> sums(n, 0);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
cin >> stacks[i][j];
sums[i] += stacks[i][j];
if (j != 0) {
is_asc[i] |= (stacks[i][j-1] < stacks[i][j]);
}
}
}
vector<deque<LL>> asc_stacks;
vector<deque<LL>> desc_stacks;
for (int i = 0; i < n; ++i) {
if (is_asc[i]) {
asc_stacks.push_back(stacks[i]);
} else {
desc_stacks.push_back(stacks[i]);
}
}
vector<LL> asc_dp = solve_asc(asc_stacks);
vector<LL> desc_dp = solve_desc(desc_stacks);
while (asc_dp.size() < k+1) asc_dp.push_back(asc_dp.back());
while (desc_dp.size() < k+1) desc_dp.push_back(desc_dp.back());
while (asc_dp.size() > k+1) asc_dp.pop_back();
while (desc_dp.size() > k+1) desc_dp.pop_back();
reverse(desc_dp.begin(), desc_dp.end());
LL maks = 0;
for (int i = 0; i < k+1; ++i) {
maks = max(maks, asc_dp[i] + desc_dp[i]);
}
cout << maks << '\n';
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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | #include <bits/stdc++.h> using namespace std; typedef long long LL; constexpr LL INF = 1'000'000'000'000'000'000LL; struct MyStack { deque<LL> stack; deque<LL> pref_sum; LL sum_query(int l, int r) { return pref_sum[r] - pref_sum[l]; } void init_pref() { pref_sum.resize(stack.size()+1); pref_sum[0] = 0; for (int i = 0; i < stack.size(); ++i) { pref_sum[i+1] = pref_sum[i] + stack[i]; } } bool operator<(const MyStack& x) const { return pref_sum.back() < x.pref_sum.back(); } }; void solve_asc_mod(vector<MyStack>& stacks, LL rem, LL n, LL m, vector<LL>& res) { multiset<LL> best_left; LL minimum = INF; for (int i = 0; i < n; ++i) { best_left.insert(stacks[i].sum_query(0, rem)); } LL all_sum = 0; for (int i = 0; i < n; ++i) { LL c1 = all_sum + *best_left.rbegin(); all_sum += stacks[i].sum_query(0, m); minimum = min(minimum, stacks[i].sum_query(rem, m)); LL c2 = all_sum - minimum; best_left.erase(best_left.find(stacks[i].sum_query(0, rem))); int idx = rem + (m*i); res[rem+(m*i)] = max(c1, c2); } if (rem == 0) { res[n*m] = all_sum; } } vector<LL> solve_asc(vector<deque<LL>>& raw_stacks) { if (raw_stacks.size() == 0) { return {0}; } LL n = raw_stacks.size(); LL m = raw_stacks[0].size(); vector<MyStack> stacks(n); for (int i = 0; i < n; ++i) { stacks[i].stack = raw_stacks[i]; stacks[i].init_pref(); } sort(stacks.rbegin(), stacks.rend()); vector<LL> res((n*m)+1, 0); for (int i = 0; i < m; ++i) { solve_asc_mod(stacks, i, n, m, res); } return res; } vector<LL> solve_desc(vector<deque<LL>>& stacks) { vector<LL> flat; for (auto& x : stacks) { for (auto& y : x) { flat.push_back(y); } } sort(flat.rbegin(), flat.rend()); vector<LL> res; res.push_back(0); for (auto& x : flat) { res.push_back(res.back() + x); } return res; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); LL n, m, k; cin >> n >> m >> k; vector<deque<LL>> stacks(n, deque<LL>(m)); deque<bool> is_asc(n, false); vector<LL> sums(n, 0); for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { cin >> stacks[i][j]; sums[i] += stacks[i][j]; if (j != 0) { is_asc[i] |= (stacks[i][j-1] < stacks[i][j]); } } } vector<deque<LL>> asc_stacks; vector<deque<LL>> desc_stacks; for (int i = 0; i < n; ++i) { if (is_asc[i]) { asc_stacks.push_back(stacks[i]); } else { desc_stacks.push_back(stacks[i]); } } vector<LL> asc_dp = solve_asc(asc_stacks); vector<LL> desc_dp = solve_desc(desc_stacks); while (asc_dp.size() < k+1) asc_dp.push_back(asc_dp.back()); while (desc_dp.size() < k+1) desc_dp.push_back(desc_dp.back()); while (asc_dp.size() > k+1) asc_dp.pop_back(); while (desc_dp.size() > k+1) desc_dp.pop_back(); reverse(desc_dp.begin(), desc_dp.end()); LL maks = 0; for (int i = 0; i < k+1; ++i) { maks = max(maks, asc_dp[i] + desc_dp[i]); } cout << maks << '\n'; return 0; } |
English