#include <algorithm> #include <cstdint> #include <cstdio> #include <ranges> #include <vector> struct Brick { Brick(const int& size_, const int& color_) : size(size_), color(color_) {} bool operator<(const Brick& brick) const { return color < brick.color; } bool operator==(const Brick& brick) const { return color == brick.color; } int size; int color; }; struct Tower { Tower() : size(0), color(0), score(0) {} Tower(const int& size_, const int& color_, const int64_t& score_) : size(size_), color(color_), score(score_) {} void addBrick(const Brick& brick, const int& c) { size = brick.size; score += size; if (brick.color != color) { score -= c; } } int size; int color; int64_t score; }; using Bricks = std::vector<Brick>; using Towers = std::vector<Tower>; void process(Towers& towers, Tower& bestTower, const Bricks& bricks, const int& c) { Tower newBestTower = bestTower; for (const auto& brick : bricks) { if (0 == towers[brick.color].score) { if (brick.size < bestTower.score + brick.size - c) { towers[brick.color] = {brick.size, brick.color, bestTower.score + brick.size - c}; } else { towers[brick.color] = {brick.size, brick.color, brick.size}; } } else { if (towers[brick.color].score + brick.size < bestTower.score + brick.size - c) { towers[brick.color].score = bestTower.score + brick.size - c; towers[brick.color].size = brick.size; } else { towers[brick.color].addBrick(brick, c); } } if (newBestTower.score < towers[brick.color].score) { newBestTower = towers[brick.color]; } } bestTower = newBestTower; } int main() { int n, c; int size, color; std::vector<Bricks> sortedBricks; int lastSize = 0; int maxColor = 0; scanf("%d %d\n", &n, &c); for (int i = 0; i < n; ++i) { scanf("%d %d\n", &size, &color); if (size != lastSize) { sortedBricks.push_back({}); } sortedBricks.back().emplace_back(size, color); lastSize = size; maxColor = std::max(maxColor, color); } for (auto& bricks : sortedBricks) { std::sort(bricks.begin(), bricks.end()); bricks.erase(std::unique(bricks.begin(), bricks.end()), bricks.end()); } Towers towers; towers.resize(maxColor + 1); for (int i = 1; i <= maxColor; ++i) { towers[i].color = i; } Tower bestTower(0, 0, 0); for (const auto& brick : sortedBricks.front()) { towers[brick.color].addBrick(brick, c); bestTower = towers[brick.color]; } for (const auto& bricks : sortedBricks | std::views::drop(1)) { process(towers, bestTower, bricks, c); } printf("%ld\n", bestTower.score); 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 | #include <algorithm> #include <cstdint> #include <cstdio> #include <ranges> #include <vector> struct Brick { Brick(const int& size_, const int& color_) : size(size_), color(color_) {} bool operator<(const Brick& brick) const { return color < brick.color; } bool operator==(const Brick& brick) const { return color == brick.color; } int size; int color; }; struct Tower { Tower() : size(0), color(0), score(0) {} Tower(const int& size_, const int& color_, const int64_t& score_) : size(size_), color(color_), score(score_) {} void addBrick(const Brick& brick, const int& c) { size = brick.size; score += size; if (brick.color != color) { score -= c; } } int size; int color; int64_t score; }; using Bricks = std::vector<Brick>; using Towers = std::vector<Tower>; void process(Towers& towers, Tower& bestTower, const Bricks& bricks, const int& c) { Tower newBestTower = bestTower; for (const auto& brick : bricks) { if (0 == towers[brick.color].score) { if (brick.size < bestTower.score + brick.size - c) { towers[brick.color] = {brick.size, brick.color, bestTower.score + brick.size - c}; } else { towers[brick.color] = {brick.size, brick.color, brick.size}; } } else { if (towers[brick.color].score + brick.size < bestTower.score + brick.size - c) { towers[brick.color].score = bestTower.score + brick.size - c; towers[brick.color].size = brick.size; } else { towers[brick.color].addBrick(brick, c); } } if (newBestTower.score < towers[brick.color].score) { newBestTower = towers[brick.color]; } } bestTower = newBestTower; } int main() { int n, c; int size, color; std::vector<Bricks> sortedBricks; int lastSize = 0; int maxColor = 0; scanf("%d %d\n", &n, &c); for (int i = 0; i < n; ++i) { scanf("%d %d\n", &size, &color); if (size != lastSize) { sortedBricks.push_back({}); } sortedBricks.back().emplace_back(size, color); lastSize = size; maxColor = std::max(maxColor, color); } for (auto& bricks : sortedBricks) { std::sort(bricks.begin(), bricks.end()); bricks.erase(std::unique(bricks.begin(), bricks.end()), bricks.end()); } Towers towers; towers.resize(maxColor + 1); for (int i = 1; i <= maxColor; ++i) { towers[i].color = i; } Tower bestTower(0, 0, 0); for (const auto& brick : sortedBricks.front()) { towers[brick.color].addBrick(brick, c); bestTower = towers[brick.color]; } for (const auto& bricks : sortedBricks | std::views::drop(1)) { process(towers, bestTower, bricks, c); } printf("%ld\n", bestTower.score); return 0; } |