#ifdef USE_PALI
#include <pali.hpp>
#else
#include <bits/stdc++.h>
#endif
using namespace std;
typedef unsigned int uint;
typedef unsigned long long ull;
struct Entry {
long long priority;
int count;
int idx;
bool operator<(const Entry &other) const
{
if (priority != other.priority)
return priority < other.priority;
if (count != other.count)
return count < other.count;
return idx < other.idx;
}
};
int REMOVED = -1;
class PriorityQueue
{
priority_queue<Entry> pq;
unordered_map<int, Entry> by_idx;
int counter;
public:
PriorityQueue() : pq(), by_idx(), counter(0) {}
void add_or_update(int idx, long long priority)
{
if (by_idx.count(idx))
remove(idx);
Entry entry{priority, counter++, idx};
by_idx[idx] = entry;
pq.push(entry);
}
void remove(int idx)
{
auto it = by_idx.find(idx);
if (it != by_idx.end()) {
Entry &entry = it->second;
entry.idx = REMOVED;
by_idx.erase(it);
}
}
pair<long long, int> pop()
{
while (!pq.empty()) {
Entry top = pq.top();
pq.pop();
if (top.idx != REMOVED) {
by_idx.erase(top.idx);
return {top.priority, top.idx};
}
}
throw runtime_error("empty");
}
bool empty() const { return pq.empty(); }
};
int main()
{
cin.tie(nullptr);
ios::sync_with_stdio(false);
uint N, M, K;
cin >> N >> M >> K;
vector<vector<ull>> asc, des;
for (uint i = 0; i < N; i++) {
vector<ull> a(M);
for (uint j = 0; j < M; j++)
cin >> a[j];
if (a[0] < a[M - 1])
asc.push_back(a);
else
des.push_back(a);
}
vector<vector<ull>> asc_sum(asc.size());
for (uint i = 0; i < asc.size(); i++) {
asc_sum[i].resize(M);
ull s = 0;
for (uint j = 0; j < M; j++) {
s += asc[i][j];
asc_sum[i][j] = s;
}
}
PriorityQueue pq;
vector<uint> des_next(des.size(), 0);
vector<ull> des_seq_sum;
ull s = 0;
for (uint i = 0; i < des.size(); i++)
if (!des[i].empty()) {
pq.add_or_update(static_cast<int>(i), static_cast<long long>(des[i][0]));
des_next[i] = 1;
}
while (!pq.empty()) {
auto [pri_, idx_] = pq.pop();
ull pri = static_cast<ull>(pri_);
uint idx = static_cast<uint>(idx_);
s += pri;
des_seq_sum.push_back(s);
if (des_next[idx] < M) {
pq.add_or_update(static_cast<int>(idx),
static_cast<long long>(des[idx][des_next[idx]]));
des_next[idx]++;
}
}
vector<vector<ull>> seq_sum = asc_sum;
seq_sum.push_back(des_seq_sum);
vector<ull> best_of(K + 1, 0);
uint at_most = 1;
for (auto &ss : seq_sum) {
vector<ull> new_best_of = best_of;
uint ss_size = static_cast<uint>(ss.size());
for (uint len = 0; len <= K; len++) {
uint start = 0;
if (len > ss_size)
start = len - ss_size;
uint end = len;
if (at_most < len)
end = at_most;
for (uint bo_taken = start; bo_taken < end; bo_taken++) {
uint ss_idx = len - bo_taken - 1;
ull candidate = best_of[bo_taken] + ss[ss_idx];
if (new_best_of[len] < candidate)
new_best_of[len] = candidate;
}
}
best_of = move(new_best_of);
if (at_most < K)
at_most += M;
}
cout << best_of[K] << "\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 140 141 142 143 144 145 146 147 148 149 150 | #ifdef USE_PALI #include <pali.hpp> #else #include <bits/stdc++.h> #endif using namespace std; typedef unsigned int uint; typedef unsigned long long ull; struct Entry { long long priority; int count; int idx; bool operator<(const Entry &other) const { if (priority != other.priority) return priority < other.priority; if (count != other.count) return count < other.count; return idx < other.idx; } }; int REMOVED = -1; class PriorityQueue { priority_queue<Entry> pq; unordered_map<int, Entry> by_idx; int counter; public: PriorityQueue() : pq(), by_idx(), counter(0) {} void add_or_update(int idx, long long priority) { if (by_idx.count(idx)) remove(idx); Entry entry{priority, counter++, idx}; by_idx[idx] = entry; pq.push(entry); } void remove(int idx) { auto it = by_idx.find(idx); if (it != by_idx.end()) { Entry &entry = it->second; entry.idx = REMOVED; by_idx.erase(it); } } pair<long long, int> pop() { while (!pq.empty()) { Entry top = pq.top(); pq.pop(); if (top.idx != REMOVED) { by_idx.erase(top.idx); return {top.priority, top.idx}; } } throw runtime_error("empty"); } bool empty() const { return pq.empty(); } }; int main() { cin.tie(nullptr); ios::sync_with_stdio(false); uint N, M, K; cin >> N >> M >> K; vector<vector<ull>> asc, des; for (uint i = 0; i < N; i++) { vector<ull> a(M); for (uint j = 0; j < M; j++) cin >> a[j]; if (a[0] < a[M - 1]) asc.push_back(a); else des.push_back(a); } vector<vector<ull>> asc_sum(asc.size()); for (uint i = 0; i < asc.size(); i++) { asc_sum[i].resize(M); ull s = 0; for (uint j = 0; j < M; j++) { s += asc[i][j]; asc_sum[i][j] = s; } } PriorityQueue pq; vector<uint> des_next(des.size(), 0); vector<ull> des_seq_sum; ull s = 0; for (uint i = 0; i < des.size(); i++) if (!des[i].empty()) { pq.add_or_update(static_cast<int>(i), static_cast<long long>(des[i][0])); des_next[i] = 1; } while (!pq.empty()) { auto [pri_, idx_] = pq.pop(); ull pri = static_cast<ull>(pri_); uint idx = static_cast<uint>(idx_); s += pri; des_seq_sum.push_back(s); if (des_next[idx] < M) { pq.add_or_update(static_cast<int>(idx), static_cast<long long>(des[idx][des_next[idx]])); des_next[idx]++; } } vector<vector<ull>> seq_sum = asc_sum; seq_sum.push_back(des_seq_sum); vector<ull> best_of(K + 1, 0); uint at_most = 1; for (auto &ss : seq_sum) { vector<ull> new_best_of = best_of; uint ss_size = static_cast<uint>(ss.size()); for (uint len = 0; len <= K; len++) { uint start = 0; if (len > ss_size) start = len - ss_size; uint end = len; if (at_most < len) end = at_most; for (uint bo_taken = start; bo_taken < end; bo_taken++) { uint ss_idx = len - bo_taken - 1; ull candidate = best_of[bo_taken] + ss[ss_idx]; if (new_best_of[len] < candidate) new_best_of[len] = candidate; } } best_of = move(new_best_of); if (at_most < K) at_most += M; } cout << best_of[K] << "\n"; return 0; } |
English