#include <algorithm> #include <iostream> #include <vector> inline long long min(const long long a, const long long b) {return (a < b ? a : b);} constexpr long long INF = 0x3FFFFFFFFFFFFFFF; constexpr int MAX_PARAM = 7000; struct {short color, mass; int price;} sweets[MAX_PARAM]; long long dp[2][MAX_PARAM]; // Price of remainder for exactly one candy of each type long long kp[MAX_PARAM]; // Price of remainder for any number of candies std::vector<short> sweetid[MAX_PARAM]; short indices[MAX_PARAM]; int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(nullptr); int num_sweets, num_colors, modulo; std::cin >> num_sweets >> num_colors >> modulo; for(int i = 0; i < num_sweets; ++i) std::cin >> sweets[i].color >> sweets[i].mass >> sweets[i].price, sweetid[--sweets[i].color].push_back(i); for(int i = 1; i < modulo; ++i) dp[1][i] = INF; for(int s = 0; s < num_colors; ++s) { for(int i = 0; i < modulo; ++i) dp[s&1][i] = INF; for(const short i : sweetid[s]) for(int j = sweets[i].mass; j < modulo+sweets[i].mass; ++j) { int idx = (j >= modulo ? j-modulo : j); dp[s&1][idx] = min(dp[s&1][idx], dp[~s&1][j-sweets[i].mass]+sweets[i].price); } } for(int i = 0; i < modulo; ++i) dp[num_colors&1][i] = dp[~num_colors&1][i]; for(int i = 1; i < modulo; ++i) kp[i] = INF; for(int i = 0; i < modulo; ++i) indices[i] = i; std::sort(indices, indices+modulo, [&](const short a, const short b) -> bool { return (dp[0][a]*(__int128)b > dp[0][b]*(__int128)a); }); for(int m = 0, k; m < modulo; ++m) { k = indices[m]; for(int i = 0, cnt = 0; cnt < modulo; ++cnt, ++i) { if(i == modulo) i = 0; int idx = (i+k >= modulo ? i+k-modulo : i+k); if(kp[idx] > kp[i]+dp[0][k]) kp[idx] = kp[i]+dp[0][k], cnt = 0; } } for(int i = 0; i < modulo; ++i) std::cout << (kp[i] == INF ? -1 : kp[i]) << '\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 | #include <algorithm> #include <iostream> #include <vector> inline long long min(const long long a, const long long b) {return (a < b ? a : b);} constexpr long long INF = 0x3FFFFFFFFFFFFFFF; constexpr int MAX_PARAM = 7000; struct {short color, mass; int price;} sweets[MAX_PARAM]; long long dp[2][MAX_PARAM]; // Price of remainder for exactly one candy of each type long long kp[MAX_PARAM]; // Price of remainder for any number of candies std::vector<short> sweetid[MAX_PARAM]; short indices[MAX_PARAM]; int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(nullptr); int num_sweets, num_colors, modulo; std::cin >> num_sweets >> num_colors >> modulo; for(int i = 0; i < num_sweets; ++i) std::cin >> sweets[i].color >> sweets[i].mass >> sweets[i].price, sweetid[--sweets[i].color].push_back(i); for(int i = 1; i < modulo; ++i) dp[1][i] = INF; for(int s = 0; s < num_colors; ++s) { for(int i = 0; i < modulo; ++i) dp[s&1][i] = INF; for(const short i : sweetid[s]) for(int j = sweets[i].mass; j < modulo+sweets[i].mass; ++j) { int idx = (j >= modulo ? j-modulo : j); dp[s&1][idx] = min(dp[s&1][idx], dp[~s&1][j-sweets[i].mass]+sweets[i].price); } } for(int i = 0; i < modulo; ++i) dp[num_colors&1][i] = dp[~num_colors&1][i]; for(int i = 1; i < modulo; ++i) kp[i] = INF; for(int i = 0; i < modulo; ++i) indices[i] = i; std::sort(indices, indices+modulo, [&](const short a, const short b) -> bool { return (dp[0][a]*(__int128)b > dp[0][b]*(__int128)a); }); for(int m = 0, k; m < modulo; ++m) { k = indices[m]; for(int i = 0, cnt = 0; cnt < modulo; ++cnt, ++i) { if(i == modulo) i = 0; int idx = (i+k >= modulo ? i+k-modulo : i+k); if(kp[idx] > kp[i]+dp[0][k]) kp[idx] = kp[i]+dp[0][k], cnt = 0; } } for(int i = 0; i < modulo; ++i) std::cout << (kp[i] == INF ? -1 : kp[i]) << '\n'; return 0; } |