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
#include <bits/stdc++.h>
#include <unordered_map>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef vector<vi> vvi;
typedef vector<bool> vb;

#define eb emplace_back
#define all(x) (x).begin(), (x).end()
#define loop(i,a,b) for (int (i) = (a); (i) < b; (i)++)
#define rloop(i,a,b) for (int (i) = (a); (i) >= b; (i)--)

bool sortow(pair<vll, ll> &a, pair<vll, ll> &b)
{
    return a.second > b.second;
}
int main()
{
    cin.tie(0)->sync_with_stdio(false);

    int n, m, k;
    ll a, b, res = 0ll;
    cin >> n >> m >> k;

    if (m == 1)
    {
        vll stosy(n);
        loop(i, 0, n) cin >> stosy[i];
        sort(all(stosy), greater<ll>());
        loop(i, 0, k) res += stosy[i];
        cout << res;
        return 0;
    }

    vector<vll> malejace;
    vector<pair<vll, ll>> rosnace;

    vll temp;
    loop(i, 0, n)
    {
        ll suma = 0ll;
        temp.resize(m);
        loop(j, 0, m) { cin >> temp[j]; suma += temp[j]; }
        if (temp[0] < temp.back())
            rosnace.emplace_back(make_pair(move(temp), suma));
        else
            malejace.emplace_back(move(temp));
    }

    vll wynikDlaMalejacych(k + 1);
    vi iteratory(malejace.size());
    priority_queue < pair<ll, int>> pq;
    loop(i, 0, malejace.size()) pq.push(make_pair(malejace[i][0], i));

    int itDlaWynMal = 1;

    while (!pq.empty() && itDlaWynMal <= k)
    {
        pair<ll, int> top = pq.top(); pq.pop();

        wynikDlaMalejacych[itDlaWynMal] = wynikDlaMalejacych[itDlaWynMal - 1] + top.first;
        itDlaWynMal++;
        iteratory[top.second]++;
        if (iteratory[top.second] < m)
            pq.push(make_pair(malejace[top.second][iteratory[top.second]], top.second));
    }
    itDlaWynMal--;
    res = max(res, wynikDlaMalejacych[min(k,itDlaWynMal)]);

    sort(all(rosnace), sortow);

    vector<vll> sPref(rosnace.size(), vll(m)), najwPrefPo(rosnace.size() + 1, vll(m,-1e18)), najwPrefPrzed(rosnace.size() + 1, vll(m,-1e18));

    loop(i, 0, rosnace.size())
    {
        sPref[i][0] = rosnace[i].first[0];
        loop(j, 1, m)
            sPref[i][j] = sPref[i][j - 1] + rosnace[i].first[j];
    }


    loop(i, 1, m) //dl_prefa
    {
        loop(j,1,rosnace.size()+1)
            najwPrefPrzed[j][i] = max(sPref[j-1][i-1]-rosnace[j-1].second, najwPrefPrzed[j-1][i]);

        rloop(j,rosnace.size()-1,0)
            najwPrefPo[j][i] = max(sPref[j][i - 1], najwPrefPo[j + 1][i]);
    }
    vll sumyPoSumach(rosnace.size() + 1);

    loop(i, 1, rosnace.size() + 1) sumyPoSumach[i] = sumyPoSumach[i - 1] + rosnace[i - 1].second;

    loop(i, 0, rosnace.size() + 1)
    {
        ll wziete = (ll)i * m;
        if (wziete<=k) res = max(res, sumyPoSumach[i] + wynikDlaMalejacych[min(k-wziete, (ll)itDlaWynMal)]);

        loop(j, 1, m)
        {
            ll wz2 = wziete + j, wz3 = (ll)(i - 1) * m + j;

            if (wz2 <= k) res = max(res, sumyPoSumach[i] + najwPrefPo[i][j] + wynikDlaMalejacych[min((ll)itDlaWynMal, k - wz2)]);
            if (i&&wz3<=k) res = max(res, sumyPoSumach[i] + najwPrefPrzed[i][j] + wynikDlaMalejacych[min((ll)itDlaWynMal, k - wz3)]);
        }
    }
    
    cout << res;

    return 0;
}