// clang-format off #include<bits/stdc++.h> using namespace std; using LL=long long; #define FOR(i,l,r) for(auto i=(l);i<=(r);++i) #define REP(i,n) FOR(i,0,(n)-1) #define ssize(x) int(x.size()) template<class A,class B>auto&operator<<(ostream&o,pair<A,B>p){return o<<"("<<p.first<<", "<<p.second<<")";} template<class T>auto operator<<(ostream&o,T x)->decltype(x.end(),o){o<<"{";int i=0;for(auto e:x)o<<(", ")+2*!i++<<e;return o<<"}";} #ifdef DEBUG #define debug(x...) cerr<<"["#x"]: ",[](auto...$){((cerr<<$<<"; "),...);}(x),cerr<<'\n' #else #define debug(...) {} #endif // clang-format on // Global variables const int max_price = 1000000000; const LL INF = numeric_limits<LL>::max() - max_price - 1; int nsweets, ncolours, mod; vector<LL> get_dp() { cin.tie(0)->sync_with_stdio(0); cin >> nsweets >> ncolours >> mod; vector<tuple<int, int, int>> sweets(nsweets); // (colour, mass, price) for (auto& sw : sweets) cin >> get<0>(sw) >> get<1>(sw) >> get<2>(sw); sort(sweets.begin(), sweets.end()); vector<LL> dp(mod, INF), odp; dp[0] = 0; int last_colour = 0; vector<bool> colours_used(ncolours); for (const auto& sw : sweets) { const auto& [colour, mass, price] = sw; colours_used[colour - 1] = true; if (last_colour != colour) { last_colour = colour; swap(dp, odp); dp.assign(mod, INF); } REP (r, mod) { int nr = r + mass; if (nr >= mod) nr -= mod; dp[nr] = min(dp[nr], odp[r] + price); } } // Edge case: some colours unused REP (c, ncolours) { if (colours_used[c]) continue; cout << "0\n"; FOR (r, 1, mod - 1) cout << "-1\n"; exit(0); } debug(dp); return dp; } int main() { // Calculate dp: min price for given remainder vector<LL> dp(get_dp()); vector<bool> optimised(mod); REP (iteration, mod) { // Find the lowest guy that is not optimised int opt = -1; REP (i, mod) { if (optimised[i]) continue; if (opt == -1) opt = i; else if (dp[i] < dp[opt]) opt = i; } if (dp[opt] == INF) break; debug(opt, dp[opt]); REP (r, mod) { if (dp[r] == INF) continue; int nr = opt + r; if (nr >= mod) nr -= mod; if (optimised[nr]) continue; dp[nr] = min(dp[nr], dp[opt] + dp[r]); } optimised[opt] = true; } debug(dp); cout << "0\n"; FOR (r, 1, mod - 1) cout << (dp[r] == INF ? -1 : dp[r]) << "\n"; #ifdef LOCAL system("grep VmPeak /proc/$PPID/status >&2"); #endif 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 | // clang-format off #include<bits/stdc++.h> using namespace std; using LL=long long; #define FOR(i,l,r) for(auto i=(l);i<=(r);++i) #define REP(i,n) FOR(i,0,(n)-1) #define ssize(x) int(x.size()) template<class A,class B>auto&operator<<(ostream&o,pair<A,B>p){return o<<"("<<p.first<<", "<<p.second<<")";} template<class T>auto operator<<(ostream&o,T x)->decltype(x.end(),o){o<<"{";int i=0;for(auto e:x)o<<(", ")+2*!i++<<e;return o<<"}";} #ifdef DEBUG #define debug(x...) cerr<<"["#x"]: ",[](auto...$){((cerr<<$<<"; "),...);}(x),cerr<<'\n' #else #define debug(...) {} #endif // clang-format on // Global variables const int max_price = 1000000000; const LL INF = numeric_limits<LL>::max() - max_price - 1; int nsweets, ncolours, mod; vector<LL> get_dp() { cin.tie(0)->sync_with_stdio(0); cin >> nsweets >> ncolours >> mod; vector<tuple<int, int, int>> sweets(nsweets); // (colour, mass, price) for (auto& sw : sweets) cin >> get<0>(sw) >> get<1>(sw) >> get<2>(sw); sort(sweets.begin(), sweets.end()); vector<LL> dp(mod, INF), odp; dp[0] = 0; int last_colour = 0; vector<bool> colours_used(ncolours); for (const auto& sw : sweets) { const auto& [colour, mass, price] = sw; colours_used[colour - 1] = true; if (last_colour != colour) { last_colour = colour; swap(dp, odp); dp.assign(mod, INF); } REP (r, mod) { int nr = r + mass; if (nr >= mod) nr -= mod; dp[nr] = min(dp[nr], odp[r] + price); } } // Edge case: some colours unused REP (c, ncolours) { if (colours_used[c]) continue; cout << "0\n"; FOR (r, 1, mod - 1) cout << "-1\n"; exit(0); } debug(dp); return dp; } int main() { // Calculate dp: min price for given remainder vector<LL> dp(get_dp()); vector<bool> optimised(mod); REP (iteration, mod) { // Find the lowest guy that is not optimised int opt = -1; REP (i, mod) { if (optimised[i]) continue; if (opt == -1) opt = i; else if (dp[i] < dp[opt]) opt = i; } if (dp[opt] == INF) break; debug(opt, dp[opt]); REP (r, mod) { if (dp[r] == INF) continue; int nr = opt + r; if (nr >= mod) nr -= mod; if (optimised[nr]) continue; dp[nr] = min(dp[nr], dp[opt] + dp[r]); } optimised[opt] = true; } debug(dp); cout << "0\n"; FOR (r, 1, mod - 1) cout << (dp[r] == INF ? -1 : dp[r]) << "\n"; #ifdef LOCAL system("grep VmPeak /proc/$PPID/status >&2"); #endif return 0; } |