#include <bits/stdc++.h>
using namespace std;
#define st first
#define nd second
#define pb push_back
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define irep(i,a,b) for(int i = a; i >= b; i--)
typedef long long ll;
typedef long double ld;
//typedef __int128 int128;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int,int> pi;
typedef pair<double,double> pd;
typedef pair<ll,ll> pl;
//iterujemy sie po k z rosnacych a potem dobieramy z malejacych
//pamietamy o tym,
vl ros;
vector<pair<ll,vl>> mal;
vector<vl> maxx;
vector<vl> minn;
vl first_k;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
ll n,m,k;
cin >> n >> m >> k;
rep(i,1,n){
vl vec;
ll sum = 0;
bool f = 1;
ll prev = 0;
rep(i,1,m){
ll x; cin >> x;
if(i != 1 && x > prev) f = 0;
sum += x;
vec.pb(x);
prev = x;
}
//cout << "i: " << i << '\n';
if(f){
//cout << "ros\n";
for(auto x:vec) ros.pb(x);
}
else
mal.pb({sum,vec});
}
sort(ros.begin(),ros.end(),greater<ll>());
first_k.resize(n*m+7);
first_k[0] = 0;
rep(j,1,k){
ll add = 0;
if(j <= ros.size()) add = ros[j-1];
first_k[j] = first_k[j-1]+add;
//cout << "j: " << j << " first_k[j]: " << first_k[j] << '\n';
}
sort(mal.begin(),mal.end());
//teraz max prefiksowe
int dl = mal.size();
rep(i,0,dl-1){
//cout << "\ni: " << i << '\n';
vl vec; vec.pb(0);
ll sum = 0;
rep(j,1,m){
sum += (mal[i].nd)[j-1];
ll val = sum;
if(i != 0) val = max(val,maxx[i-1][j]);
vec.pb(val);
//cout << "j: " << j << " maxx: " << val << '\n';
}
maxx.pb(vec);
}
//zle zalozenia xDDDD
//to ze nie bede dwoch zaczynal to fakt!!!
//ale ktore bierzemy jako nasze zaczete nie skonczone?
//aha jeszcze pref sufiksowe???
//czyli bedzie cos w stylu ile zabieramy czyli suma_do_k-suma_calosc i z tego min??
//cos takiego dla kazdego k i wtedy mozemy calosc z ind-1
minn.resize(dl);
irep(i,dl-1,0){
//bierzemy o 1
ll sum = 0;
//mal[i].st - sum - ile odejmujemy!!!
minn[i].pb(mal[i].st);
//cout << "\ni: " << i << '\n';
rep(j,1,m){
sum += (mal[i].nd)[j-1];
if(i == dl-1) minn[i].pb(mal[i].st - sum);
else minn[i].pb(min(minn[i+1][j], mal[i].st - sum));
//cout << "j: " << j << " min: " << minn[i][j] << '\n';
}
}
//stworzone sumy!!!
//t - ile bierzemy z naszego
ll ans = 0;
ll akt_whole = 0;
ll ind = dl;
rep(t,0,k){
if(t != 0 && t%m == 0 && ind != 0){
ind--;
akt_whole += mal[ind].st;
}
ll v1 = 0;
if(ind > 0) v1 = maxx[ind-1][t%m];
ll v2 = 0;
if(ind > 0 && ind < dl) v2 = mal[ind-1].st - minn[ind][t%m];
//cout << "t: " << t << " akt_whole: " << akt_whole << " ind: " << ind
// << " v1: " << v1 << " v2: " << v2 << '\n';
ans = max(ans,first_k[k-t] + akt_whole + max(v1,v2));
}
cout << ans;
return 0;
}
/*
test 203
test 340
test 7379
*/
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 | #include <bits/stdc++.h> using namespace std; #define st first #define nd second #define pb push_back #define rep(i,a,b) for(int i = a; i <= b; i++) #define irep(i,a,b) for(int i = a; i >= b; i--) typedef long long ll; typedef long double ld; //typedef __int128 int128; typedef vector<int> vi; typedef vector<ll> vl; typedef pair<int,int> pi; typedef pair<double,double> pd; typedef pair<ll,ll> pl; //iterujemy sie po k z rosnacych a potem dobieramy z malejacych //pamietamy o tym, vl ros; vector<pair<ll,vl>> mal; vector<vl> maxx; vector<vl> minn; vl first_k; int main(){ ios::sync_with_stdio(0); cin.tie(0); ll n,m,k; cin >> n >> m >> k; rep(i,1,n){ vl vec; ll sum = 0; bool f = 1; ll prev = 0; rep(i,1,m){ ll x; cin >> x; if(i != 1 && x > prev) f = 0; sum += x; vec.pb(x); prev = x; } //cout << "i: " << i << '\n'; if(f){ //cout << "ros\n"; for(auto x:vec) ros.pb(x); } else mal.pb({sum,vec}); } sort(ros.begin(),ros.end(),greater<ll>()); first_k.resize(n*m+7); first_k[0] = 0; rep(j,1,k){ ll add = 0; if(j <= ros.size()) add = ros[j-1]; first_k[j] = first_k[j-1]+add; //cout << "j: " << j << " first_k[j]: " << first_k[j] << '\n'; } sort(mal.begin(),mal.end()); //teraz max prefiksowe int dl = mal.size(); rep(i,0,dl-1){ //cout << "\ni: " << i << '\n'; vl vec; vec.pb(0); ll sum = 0; rep(j,1,m){ sum += (mal[i].nd)[j-1]; ll val = sum; if(i != 0) val = max(val,maxx[i-1][j]); vec.pb(val); //cout << "j: " << j << " maxx: " << val << '\n'; } maxx.pb(vec); } //zle zalozenia xDDDD //to ze nie bede dwoch zaczynal to fakt!!! //ale ktore bierzemy jako nasze zaczete nie skonczone? //aha jeszcze pref sufiksowe??? //czyli bedzie cos w stylu ile zabieramy czyli suma_do_k-suma_calosc i z tego min?? //cos takiego dla kazdego k i wtedy mozemy calosc z ind-1 minn.resize(dl); irep(i,dl-1,0){ //bierzemy o 1 ll sum = 0; //mal[i].st - sum - ile odejmujemy!!! minn[i].pb(mal[i].st); //cout << "\ni: " << i << '\n'; rep(j,1,m){ sum += (mal[i].nd)[j-1]; if(i == dl-1) minn[i].pb(mal[i].st - sum); else minn[i].pb(min(minn[i+1][j], mal[i].st - sum)); //cout << "j: " << j << " min: " << minn[i][j] << '\n'; } } //stworzone sumy!!! //t - ile bierzemy z naszego ll ans = 0; ll akt_whole = 0; ll ind = dl; rep(t,0,k){ if(t != 0 && t%m == 0 && ind != 0){ ind--; akt_whole += mal[ind].st; } ll v1 = 0; if(ind > 0) v1 = maxx[ind-1][t%m]; ll v2 = 0; if(ind > 0 && ind < dl) v2 = mal[ind-1].st - minn[ind][t%m]; //cout << "t: " << t << " akt_whole: " << akt_whole << " ind: " << ind // << " v1: " << v1 << " v2: " << v2 << '\n'; ans = max(ans,first_k[k-t] + akt_whole + max(v1,v2)); } cout << ans; return 0; } /* test 203 test 340 test 7379 */ |
English