// Online C++ compiler to run C++ program online #include <iostream> #include <vector> #include <queue> #include <unordered_set> #include <climits> using namespace std; int main() { // Write C++ code here int n, k, m; cin >> n >> k >> m; // n - liczba rodzajow zelek // k - liczba kolorow // m - reszty vector<vector<int>> cena_pk_pm(k, vector<int>(m, INT_MAX)); vector<unordered_set<int>> masy_pk(k, unordered_set<int>()); for(int i = 0; i < n; i++) { int kolor, masa, cena; cin >> kolor >> masa >> cena; masa %= m; kolor--; cena_pk_pm[kolor][masa] = min(cena_pk_pm[kolor][masa], cena); masy_pk[kolor].insert(masa); } //for(int i = 0; i < k; i++) { //for(int j = 0; j < m; j++) if(cena_pk_pm[i][j] == INT_MAX) cout << -1 << " "; else cout << cena_pk_pm[i][j] << " "; //cout << endl; //} //cout << endl << "siema" << endl; vector<vector<long long int>> dp(k, vector<long long int>(m, LLONG_MAX)); // dp[i][j] - jak najtaniej dostac reszte j uzywajac kolorow 0 ... i // wypelnij pierwszy wiersz - tylko pierwszy kolor for(int i = 0; i < m; i++) { if(cena_pk_pm[0][i] != INT_MAX) dp[0][i] = cena_pk_pm[0][i]; } // wypelnij reszte wierszy for(int i = 1; i < k; i++) { // kolor i // dla kazdej zelki tego koloru i kazdej reszty sprawdz jak najtaniej dostac taka reszte for(int masa_zelki : masy_pk[i]) { for(int r = 0; r < m; r++) { int brakujaca_masa = (r + m - masa_zelki) % m; if(dp[i-1][brakujaca_masa] != LLONG_MAX) { dp[i][r] = min(dp[i][r], dp[i-1][brakujaca_masa] + cena_pk_pm[i][masa_zelki]); } } } } // dp[k-1] gotowe - przy uzyciu 1 zelki. vector<long long int> aktualne = dp[k-1]; vector<bool> inqueue(m, false); queue<int> q; for(int i = 0; i < m; i++) { if(aktualne[i] != LLONG_MAX) { inqueue[i] = true; q.push(i); } } while(!q.empty()) { int r = q.front(); q.pop(); inqueue[r] = false; if(aktualne[r] == LLONG_MAX) continue; for(int i = 0; i < m; i++) { if(aktualne[i] == LLONG_MAX) continue; int r2 = (r + i) % m; if(aktualne[r2] > aktualne[r] + aktualne[i]) { aktualne[r2] = aktualne[r] + aktualne[i]; if(!inqueue[r2]) q.push(r2); } } } cout << 0 << endl; for(int i = 1; i < m; i++) { if(aktualne[i] == LLONG_MAX) cout << -1 << endl; else cout << aktualne[i] << endl; } 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 | // Online C++ compiler to run C++ program online #include <iostream> #include <vector> #include <queue> #include <unordered_set> #include <climits> using namespace std; int main() { // Write C++ code here int n, k, m; cin >> n >> k >> m; // n - liczba rodzajow zelek // k - liczba kolorow // m - reszty vector<vector<int>> cena_pk_pm(k, vector<int>(m, INT_MAX)); vector<unordered_set<int>> masy_pk(k, unordered_set<int>()); for(int i = 0; i < n; i++) { int kolor, masa, cena; cin >> kolor >> masa >> cena; masa %= m; kolor--; cena_pk_pm[kolor][masa] = min(cena_pk_pm[kolor][masa], cena); masy_pk[kolor].insert(masa); } //for(int i = 0; i < k; i++) { //for(int j = 0; j < m; j++) if(cena_pk_pm[i][j] == INT_MAX) cout << -1 << " "; else cout << cena_pk_pm[i][j] << " "; //cout << endl; //} //cout << endl << "siema" << endl; vector<vector<long long int>> dp(k, vector<long long int>(m, LLONG_MAX)); // dp[i][j] - jak najtaniej dostac reszte j uzywajac kolorow 0 ... i // wypelnij pierwszy wiersz - tylko pierwszy kolor for(int i = 0; i < m; i++) { if(cena_pk_pm[0][i] != INT_MAX) dp[0][i] = cena_pk_pm[0][i]; } // wypelnij reszte wierszy for(int i = 1; i < k; i++) { // kolor i // dla kazdej zelki tego koloru i kazdej reszty sprawdz jak najtaniej dostac taka reszte for(int masa_zelki : masy_pk[i]) { for(int r = 0; r < m; r++) { int brakujaca_masa = (r + m - masa_zelki) % m; if(dp[i-1][brakujaca_masa] != LLONG_MAX) { dp[i][r] = min(dp[i][r], dp[i-1][brakujaca_masa] + cena_pk_pm[i][masa_zelki]); } } } } // dp[k-1] gotowe - przy uzyciu 1 zelki. vector<long long int> aktualne = dp[k-1]; vector<bool> inqueue(m, false); queue<int> q; for(int i = 0; i < m; i++) { if(aktualne[i] != LLONG_MAX) { inqueue[i] = true; q.push(i); } } while(!q.empty()) { int r = q.front(); q.pop(); inqueue[r] = false; if(aktualne[r] == LLONG_MAX) continue; for(int i = 0; i < m; i++) { if(aktualne[i] == LLONG_MAX) continue; int r2 = (r + i) % m; if(aktualne[r2] > aktualne[r] + aktualne[i]) { aktualne[r2] = aktualne[r] + aktualne[i]; if(!inqueue[r2]) q.push(r2); } } } cout << 0 << endl; for(int i = 1; i < m; i++) { if(aktualne[i] == LLONG_MAX) cout << -1 << endl; else cout << aktualne[i] << endl; } return 0; } |