#include <iostream> #include <vector> #include <chrono> #include <unordered_map> #include <tuple> using namespace std; struct tuple_hash { template <class T> inline void hash_combine(std::size_t& seed, const T& val) const { seed ^= std::hash<T>{}(val)+0x9e3779b9 + (seed << 6) + (seed >> 2); } size_t operator()(const tuple<int, int, int>& t) const { size_t seed = 0; hash_combine(seed, get<0>(t)); hash_combine(seed, get<1>(t)); hash_combine(seed, get<2>(t)); return seed; } }; unordered_map<tuple<int, int, int>, long long, tuple_hash> memo; static long long towerHeight(int n, int c, int lastSize, int lastColor, int fromCube, const vector<pair<int, int>>& cubes) { if (fromCube == n) return 0; // Pomijamy long long height1 = 0; if (fromCube + 1 < n) { if (memo.find({ lastSize, lastColor, fromCube + 1 }) != memo.end()) height1 = memo[{lastSize, lastColor, fromCube + 1}]; else { height1 = towerHeight(n, c, lastSize, lastColor, fromCube + 1, cubes); memo[{lastSize, lastColor, fromCube + 1}] = height1; } } // Niepomijamy long long height2 = 0; if (lastSize < cubes[fromCube].first) { height2 = cubes[fromCube].first; if (lastColor > 0 && cubes[fromCube].second != lastColor) height2 -= c; if (fromCube + 1 < n) { long long h; if (memo.find({ cubes[fromCube].first, cubes[fromCube].second, fromCube + 1}) != memo.end()) h = memo[{cubes[fromCube].first, cubes[fromCube].second, fromCube + 1}]; else { h = towerHeight(n, c, cubes[fromCube].first, cubes[fromCube].second, fromCube + 1, cubes); memo[{cubes[fromCube].first, cubes[fromCube].second, fromCube + 1}] = h; } height2 += h; } } return (height1 > height2) ? height1 : height2; } int main() { int n; int c; cin >> n >> c; vector<pair<int, int>> cubes; for (int i = 0; i < n; i++) { int a; int w; cin >> a >> w; cubes.push_back({ a,w }); } auto start = chrono::steady_clock::now(); long long height = towerHeight(n, c, 0, 0, 0, cubes); cout << height << endl; //auto end = chrono::steady_clock::now(); //chrono::duration<double> elapsed_seconds = end - start; //cout << "Czas: " << elapsed_seconds.count() << endl; }
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 | #include <iostream> #include <vector> #include <chrono> #include <unordered_map> #include <tuple> using namespace std; struct tuple_hash { template <class T> inline void hash_combine(std::size_t& seed, const T& val) const { seed ^= std::hash<T>{}(val)+0x9e3779b9 + (seed << 6) + (seed >> 2); } size_t operator()(const tuple<int, int, int>& t) const { size_t seed = 0; hash_combine(seed, get<0>(t)); hash_combine(seed, get<1>(t)); hash_combine(seed, get<2>(t)); return seed; } }; unordered_map<tuple<int, int, int>, long long, tuple_hash> memo; static long long towerHeight(int n, int c, int lastSize, int lastColor, int fromCube, const vector<pair<int, int>>& cubes) { if (fromCube == n) return 0; // Pomijamy long long height1 = 0; if (fromCube + 1 < n) { if (memo.find({ lastSize, lastColor, fromCube + 1 }) != memo.end()) height1 = memo[{lastSize, lastColor, fromCube + 1}]; else { height1 = towerHeight(n, c, lastSize, lastColor, fromCube + 1, cubes); memo[{lastSize, lastColor, fromCube + 1}] = height1; } } // Niepomijamy long long height2 = 0; if (lastSize < cubes[fromCube].first) { height2 = cubes[fromCube].first; if (lastColor > 0 && cubes[fromCube].second != lastColor) height2 -= c; if (fromCube + 1 < n) { long long h; if (memo.find({ cubes[fromCube].first, cubes[fromCube].second, fromCube + 1}) != memo.end()) h = memo[{cubes[fromCube].first, cubes[fromCube].second, fromCube + 1}]; else { h = towerHeight(n, c, cubes[fromCube].first, cubes[fromCube].second, fromCube + 1, cubes); memo[{cubes[fromCube].first, cubes[fromCube].second, fromCube + 1}] = h; } height2 += h; } } return (height1 > height2) ? height1 : height2; } int main() { int n; int c; cin >> n >> c; vector<pair<int, int>> cubes; for (int i = 0; i < n; i++) { int a; int w; cin >> a >> w; cubes.push_back({ a,w }); } auto start = chrono::steady_clock::now(); long long height = towerHeight(n, c, 0, 0, 0, cubes); cout << height << endl; //auto end = chrono::steady_clock::now(); //chrono::duration<double> elapsed_seconds = end - start; //cout << "Czas: " << elapsed_seconds.count() << endl; } |