#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <cmath>
struct StosRosnacy
{
std::vector<long long> kolejneSumy;
};
int main()
{
std::ios_base::sync_with_stdio(false);
std::cin.tie(NULL);
int n;
int m;
int k;
std::cin >> n >> m >> k;
std::vector<long long> nalesnikiWStosachMalejacych;
std::vector<StosRosnacy> stosyRosnace;
for (int i = 0; i < n; ++i)
{
std::vector<long long> rozmiaryNalesnikow;
for (int j = 0; j < m; ++j)
{
long long rozmiar;
std::cin >> rozmiar;
rozmiaryNalesnikow.push_back(rozmiar);
}
if (rozmiaryNalesnikow[0] >= rozmiaryNalesnikow.back())
{
for (int j = 0; j < m; ++j)
{
nalesnikiWStosachMalejacych.push_back(rozmiaryNalesnikow[j]);
}
}
else
{
StosRosnacy stosRosnacy;
stosRosnacy.kolejneSumy.reserve(m);
long long suma = 0;
for (int j = 0; j < m; ++j)
{
suma += rozmiaryNalesnikow[j];
stosRosnacy.kolejneSumy.push_back(suma);
}
stosyRosnace.push_back(stosRosnacy);
}
}
std::stable_sort(nalesnikiWStosachMalejacych.begin(), nalesnikiWStosachMalejacych.end(), [](long long a, long long b) { return a > b; });
std::vector<long long> iloscUzyskanychWStosachMalejacych(nalesnikiWStosachMalejacych.size() + 1);
long long suma = 0;
for (int i = 0; i <= nalesnikiWStosachMalejacych.size(); ++i)
{
iloscUzyskanychWStosachMalejacych[i] = suma;
if (i < nalesnikiWStosachMalejacych.size())
suma += nalesnikiWStosachMalejacych[i];
}
std::stable_sort(stosyRosnace.begin(), stosyRosnace.end(), [](StosRosnacy const& a, StosRosnacy const& b) { return a.kolejneSumy.back() > b.kolejneSumy.back(); });
std::vector<long long> iloscUzyskanychWStosachRosnacych(stosyRosnace.size() * m + 1);
long long sumaCalych = 0;
for (int i = 0; i <= stosyRosnace.size(); ++i)
{
iloscUzyskanychWStosachRosnacych[i * m] = sumaCalych;
if (i< stosyRosnace.size())
sumaCalych += stosyRosnace[i].kolejneSumy.back();
}
for (int reszta = 1; reszta < m; ++reszta)
{
std::multiset<long long> dlugosciKrotszegoCiagu;
for (int i = 0; i < stosyRosnace.size(); ++i)
{
dlugosciKrotszegoCiagu.insert(stosyRosnace[i].kolejneSumy[reszta - 1]);
}
sumaCalych = 0;
for (int i = 0; i < stosyRosnace.size(); ++i)
{
iloscUzyskanychWStosachRosnacych[i * m + reszta] = std::max(iloscUzyskanychWStosachRosnacych[i * m + reszta], sumaCalych + *dlugosciKrotszegoCiagu.rbegin());
sumaCalych += stosyRosnace[i].kolejneSumy.back();
dlugosciKrotszegoCiagu.erase(dlugosciKrotszegoCiagu.lower_bound(stosyRosnace[i].kolejneSumy[reszta-1])); // usuwa jeden element
}
std::set<long long> rozniceMiedzyKrotszymICalym;
sumaCalych = 0;
for (int i = 0; i < stosyRosnace.size(); ++i)
{
sumaCalych += stosyRosnace[i].kolejneSumy.back();
rozniceMiedzyKrotszymICalym.insert(stosyRosnace[i].kolejneSumy[reszta - 1] - stosyRosnace[i].kolejneSumy.back());
iloscUzyskanychWStosachRosnacych[i * m + reszta] = std::max(iloscUzyskanychWStosachRosnacych[i * m + reszta],
sumaCalych + *rozniceMiedzyKrotszymICalym.rbegin());
}
}
long long max = 0;
for (int i = 0; i <= std::min(k, (int)iloscUzyskanychWStosachMalejacych.size() - 1); ++i)
{
if (k - i < iloscUzyskanychWStosachRosnacych.size())
max = std::max(max, iloscUzyskanychWStosachMalejacych[i] + iloscUzyskanychWStosachRosnacych[k - i]);
}
std::cout << max << "\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 | #include <iostream> #include <vector> #include <set> #include <algorithm> #include <cmath> struct StosRosnacy { std::vector<long long> kolejneSumy; }; int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); int n; int m; int k; std::cin >> n >> m >> k; std::vector<long long> nalesnikiWStosachMalejacych; std::vector<StosRosnacy> stosyRosnace; for (int i = 0; i < n; ++i) { std::vector<long long> rozmiaryNalesnikow; for (int j = 0; j < m; ++j) { long long rozmiar; std::cin >> rozmiar; rozmiaryNalesnikow.push_back(rozmiar); } if (rozmiaryNalesnikow[0] >= rozmiaryNalesnikow.back()) { for (int j = 0; j < m; ++j) { nalesnikiWStosachMalejacych.push_back(rozmiaryNalesnikow[j]); } } else { StosRosnacy stosRosnacy; stosRosnacy.kolejneSumy.reserve(m); long long suma = 0; for (int j = 0; j < m; ++j) { suma += rozmiaryNalesnikow[j]; stosRosnacy.kolejneSumy.push_back(suma); } stosyRosnace.push_back(stosRosnacy); } } std::stable_sort(nalesnikiWStosachMalejacych.begin(), nalesnikiWStosachMalejacych.end(), [](long long a, long long b) { return a > b; }); std::vector<long long> iloscUzyskanychWStosachMalejacych(nalesnikiWStosachMalejacych.size() + 1); long long suma = 0; for (int i = 0; i <= nalesnikiWStosachMalejacych.size(); ++i) { iloscUzyskanychWStosachMalejacych[i] = suma; if (i < nalesnikiWStosachMalejacych.size()) suma += nalesnikiWStosachMalejacych[i]; } std::stable_sort(stosyRosnace.begin(), stosyRosnace.end(), [](StosRosnacy const& a, StosRosnacy const& b) { return a.kolejneSumy.back() > b.kolejneSumy.back(); }); std::vector<long long> iloscUzyskanychWStosachRosnacych(stosyRosnace.size() * m + 1); long long sumaCalych = 0; for (int i = 0; i <= stosyRosnace.size(); ++i) { iloscUzyskanychWStosachRosnacych[i * m] = sumaCalych; if (i< stosyRosnace.size()) sumaCalych += stosyRosnace[i].kolejneSumy.back(); } for (int reszta = 1; reszta < m; ++reszta) { std::multiset<long long> dlugosciKrotszegoCiagu; for (int i = 0; i < stosyRosnace.size(); ++i) { dlugosciKrotszegoCiagu.insert(stosyRosnace[i].kolejneSumy[reszta - 1]); } sumaCalych = 0; for (int i = 0; i < stosyRosnace.size(); ++i) { iloscUzyskanychWStosachRosnacych[i * m + reszta] = std::max(iloscUzyskanychWStosachRosnacych[i * m + reszta], sumaCalych + *dlugosciKrotszegoCiagu.rbegin()); sumaCalych += stosyRosnace[i].kolejneSumy.back(); dlugosciKrotszegoCiagu.erase(dlugosciKrotszegoCiagu.lower_bound(stosyRosnace[i].kolejneSumy[reszta-1])); // usuwa jeden element } std::set<long long> rozniceMiedzyKrotszymICalym; sumaCalych = 0; for (int i = 0; i < stosyRosnace.size(); ++i) { sumaCalych += stosyRosnace[i].kolejneSumy.back(); rozniceMiedzyKrotszymICalym.insert(stosyRosnace[i].kolejneSumy[reszta - 1] - stosyRosnace[i].kolejneSumy.back()); iloscUzyskanychWStosachRosnacych[i * m + reszta] = std::max(iloscUzyskanychWStosachRosnacych[i * m + reszta], sumaCalych + *rozniceMiedzyKrotszymICalym.rbegin()); } } long long max = 0; for (int i = 0; i <= std::min(k, (int)iloscUzyskanychWStosachMalejacych.size() - 1); ++i) { if (k - i < iloscUzyskanychWStosachRosnacych.size()) max = std::max(max, iloscUzyskanychWStosachMalejacych[i] + iloscUzyskanychWStosachRosnacych[k - i]); } std::cout << max << "\n"; return 0; } |
English