#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i = (a); i < (b); i++)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
#define ST first
#define ND second
#define PB push_back
using ll = long long;
using ld = long double;
using pi = pair<int,int>;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
#ifdef LOCAL
#define DTP(x, y) \
auto operator<<(auto &o, auto a)->decltype(y, o) \
{ \
o << "("; \
x; \
return o << ")"; \
}
DTP(o << a.first << ", " << a.second, a.second);
DTP(for (auto i : a) o << i << ", ", all(a));
void dump(auto... x) { ((cerr << x << ", "), ...) << '\n'; }
#define debug(x...) cerr << setw(4) << __LINE__ << ":[" #x "]: ", dump(x)
#else
#define debug(...) 0
#endif
bool cmp(vll &A, vll &B){
return (A[0]>B[0]);
}
void Solve()
{
ll n, m, k;
cin >> n >> m >> k;
vector<vector<ll>> A;
vector<vector<ll>> R;
rep(j, 0, n){
vector<ll> T(m);
bool rev=true;
rep(i, 0, m){
cin >> T[i];
if(i && T[i]>T[i-1])
rev=false;
}
reverse(all(T));
T.PB(0);
if(rev)
R.PB(T);
for(int i=m-1; i>=0; --i)
T[i]+=T[i+1];
if(!rev)
A.PB(T);
}
vector<ll> Rev_ans(sz(R)*m+1);
vi I(sz(R), m-1);
priority_queue<pair<ll,int>> Q;
rep(i, 0, sz(R)){
Q.push(pair<ll,int>(R[i][m-1], i));
}
rep(i, 1, sz(R)*m+1){
pair<ll,int> x=Q.top();
Q.pop();
Rev_ans[i]=Rev_ans[i-1]+x.ST;
if(I[x.ND]>0){
--I[x.ND];
Q.push(pair<ll,int>(R[x.ND][I[x.ND]], x.ND));
}
}
n=sz(A);
sort(all(A), cmp);
vll Ans(n*m+1);
if(n>0){
vll Pref(n);
Pref[0]=A[0][0];
rep(i, 1, n)
Pref[i]=Pref[i-1]+A[i][0];
Ans[n*m]=Pref[n-1];
for(ll i=0; i<m; ++i){ // Bierzemy pierwsze do j-1 włącznie, z reszty 1 wierzch dł. i
ll ma=0;
for(ll j=n-1; j>=0; --j){
ma=max(ma, A[j][m-i]);
if(j==0){
Ans[i]=ma;
}else{
Ans[(j)*m+i]=Pref[j-1]+ma;
}
}
}
for(ll i=1; i<m; ++i){ // Z pierwszych do j-tego włącznie z jednego bierzemy tylko m-i górnych
ll mi=1000'000'000'000'000'000;
for(ll j=0; j<n; ++j){
mi=min(mi, A[j][0]-A[j][i]);
Ans[(j+1)*m-i]=max(Ans[(j+1)*m-i], Pref[j]-mi);
}
}
}
ll res=0;
rep(i, 0, sz(Ans)){
if(k-i>=0 && k-i<sz(Rev_ans) && res<Ans[i]+Rev_ans[k-i])
res=Ans[i]+Rev_ans[k-i];
}
cout << res << "\n";
return;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
int t=1;
// cin >> t;
while(t--)
{
Solve();
}
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 | #include<bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i = (a); i < (b); i++) #define all(x) begin(x), end(x) #define sz(x) (int)(x).size() #define ST first #define ND second #define PB push_back using ll = long long; using ld = long double; using pi = pair<int,int>; using vi = vector<int>; using vvi = vector<vi>; using vll = vector<ll>; #ifdef LOCAL #define DTP(x, y) \ auto operator<<(auto &o, auto a)->decltype(y, o) \ { \ o << "("; \ x; \ return o << ")"; \ } DTP(o << a.first << ", " << a.second, a.second); DTP(for (auto i : a) o << i << ", ", all(a)); void dump(auto... x) { ((cerr << x << ", "), ...) << '\n'; } #define debug(x...) cerr << setw(4) << __LINE__ << ":[" #x "]: ", dump(x) #else #define debug(...) 0 #endif bool cmp(vll &A, vll &B){ return (A[0]>B[0]); } void Solve() { ll n, m, k; cin >> n >> m >> k; vector<vector<ll>> A; vector<vector<ll>> R; rep(j, 0, n){ vector<ll> T(m); bool rev=true; rep(i, 0, m){ cin >> T[i]; if(i && T[i]>T[i-1]) rev=false; } reverse(all(T)); T.PB(0); if(rev) R.PB(T); for(int i=m-1; i>=0; --i) T[i]+=T[i+1]; if(!rev) A.PB(T); } vector<ll> Rev_ans(sz(R)*m+1); vi I(sz(R), m-1); priority_queue<pair<ll,int>> Q; rep(i, 0, sz(R)){ Q.push(pair<ll,int>(R[i][m-1], i)); } rep(i, 1, sz(R)*m+1){ pair<ll,int> x=Q.top(); Q.pop(); Rev_ans[i]=Rev_ans[i-1]+x.ST; if(I[x.ND]>0){ --I[x.ND]; Q.push(pair<ll,int>(R[x.ND][I[x.ND]], x.ND)); } } n=sz(A); sort(all(A), cmp); vll Ans(n*m+1); if(n>0){ vll Pref(n); Pref[0]=A[0][0]; rep(i, 1, n) Pref[i]=Pref[i-1]+A[i][0]; Ans[n*m]=Pref[n-1]; for(ll i=0; i<m; ++i){ // Bierzemy pierwsze do j-1 włącznie, z reszty 1 wierzch dł. i ll ma=0; for(ll j=n-1; j>=0; --j){ ma=max(ma, A[j][m-i]); if(j==0){ Ans[i]=ma; }else{ Ans[(j)*m+i]=Pref[j-1]+ma; } } } for(ll i=1; i<m; ++i){ // Z pierwszych do j-tego włącznie z jednego bierzemy tylko m-i górnych ll mi=1000'000'000'000'000'000; for(ll j=0; j<n; ++j){ mi=min(mi, A[j][0]-A[j][i]); Ans[(j+1)*m-i]=max(Ans[(j+1)*m-i], Pref[j]-mi); } } } ll res=0; rep(i, 0, sz(Ans)){ if(k-i>=0 && k-i<sz(Rev_ans) && res<Ans[i]+Rev_ans[k-i]) res=Ans[i]+Rev_ans[k-i]; } cout << res << "\n"; return; } int main() { ios_base::sync_with_stdio(false); cin.tie(0); int t=1; // cin >> t; while(t--) { Solve(); } return 0; } |
English