#include<bits/stdc++.h> using namespace std; const int N = 7008; const long long inf = 1e18; int n, m, k; struct zelek{ int kolor; int masa; long long cena; }; bool operator< (zelek a, zelek b){ if(a.kolor<b.kolor) return 1; if(a.kolor > b.kolor) return 0; if(a.cena < b.cena) return 1; if(a.cena > b.cena) return 0; return (a.masa > b.masa); } vector<zelek> haribo; long long nowedp[N]; long long dp[N]; struct zestaw{ int masa; long long koszt; }; bool operator< (zestaw a, zestaw b){ if(a.koszt<b.koszt) return 1; if(b.koszt<a.koszt) return 0; return (a.masa < b.masa); } bool useless[N]; bool odw[N]; vector<zestaw> smiejzelki; int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cin >> n >> k >> m; zelek nowyzelek; for(int i=0; i<n; i++){ cin >> nowyzelek.kolor >> nowyzelek.masa >> nowyzelek.cena; haribo.push_back(nowyzelek); } sort(haribo.begin(), haribo.end()); int licznikkolorow=0; int poprzednikolor = 0; for(int i=1; i<m; i++) nowedp[i] = inf; for(int i=0; i<haribo.size(); i++){ zelek zel = haribo[i]; if(zel.kolor!=poprzednikolor){ licznikkolorow++; poprzednikolor = zel.kolor; for(int i=0; i<m; i++){ dp[i] = nowedp[i]; nowedp[i]=inf; } } for(int i=0; i<m; i++){ nowedp[i] = min(nowedp[i], dp[(i-zel.masa + m)%m]+zel.cena); } } if(licznikkolorow<k){ cout <<"0\n"; for(int i=1; i<m; i++) cout << "-1\n"; return 0; } zestaw nowyzestaw; for(int i=0; i<m; i++){ if(nowedp[i]<inf){ nowyzestaw.koszt = nowedp[i]; nowyzestaw.masa = i; smiejzelki.push_back(nowyzestaw); } } sort(smiejzelki.begin(), smiejzelki.end()); nowedp[0]=0; for(auto zes : smiejzelki){ int mas = zes.masa; int cost = zes.koszt; if(useless[mas]) continue; for(int i=0; i<m; i++) odw[i]=0; for(int j=0; j<m; j++){ long long mini=nowedp[j]; int licz = j; if(odw[j]) continue; for(int i=0; i<=2*n; i++){ if(nowedp[licz]>mini){ nowedp[licz] = mini; useless[licz]=1; } else{ mini = nowedp[licz]; } mini+=cost; licz+=mas; licz%=m; if(odw[licz]) break; odw[licz] = 1; } } } for(int i=0; i<m; i++){ if(nowedp[i]>=1e18) cout << "-1\n"; else cout << nowedp[i]<<"\n"; } }
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 101 102 103 104 | #include<bits/stdc++.h> using namespace std; const int N = 7008; const long long inf = 1e18; int n, m, k; struct zelek{ int kolor; int masa; long long cena; }; bool operator< (zelek a, zelek b){ if(a.kolor<b.kolor) return 1; if(a.kolor > b.kolor) return 0; if(a.cena < b.cena) return 1; if(a.cena > b.cena) return 0; return (a.masa > b.masa); } vector<zelek> haribo; long long nowedp[N]; long long dp[N]; struct zestaw{ int masa; long long koszt; }; bool operator< (zestaw a, zestaw b){ if(a.koszt<b.koszt) return 1; if(b.koszt<a.koszt) return 0; return (a.masa < b.masa); } bool useless[N]; bool odw[N]; vector<zestaw> smiejzelki; int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cin >> n >> k >> m; zelek nowyzelek; for(int i=0; i<n; i++){ cin >> nowyzelek.kolor >> nowyzelek.masa >> nowyzelek.cena; haribo.push_back(nowyzelek); } sort(haribo.begin(), haribo.end()); int licznikkolorow=0; int poprzednikolor = 0; for(int i=1; i<m; i++) nowedp[i] = inf; for(int i=0; i<haribo.size(); i++){ zelek zel = haribo[i]; if(zel.kolor!=poprzednikolor){ licznikkolorow++; poprzednikolor = zel.kolor; for(int i=0; i<m; i++){ dp[i] = nowedp[i]; nowedp[i]=inf; } } for(int i=0; i<m; i++){ nowedp[i] = min(nowedp[i], dp[(i-zel.masa + m)%m]+zel.cena); } } if(licznikkolorow<k){ cout <<"0\n"; for(int i=1; i<m; i++) cout << "-1\n"; return 0; } zestaw nowyzestaw; for(int i=0; i<m; i++){ if(nowedp[i]<inf){ nowyzestaw.koszt = nowedp[i]; nowyzestaw.masa = i; smiejzelki.push_back(nowyzestaw); } } sort(smiejzelki.begin(), smiejzelki.end()); nowedp[0]=0; for(auto zes : smiejzelki){ int mas = zes.masa; int cost = zes.koszt; if(useless[mas]) continue; for(int i=0; i<m; i++) odw[i]=0; for(int j=0; j<m; j++){ long long mini=nowedp[j]; int licz = j; if(odw[j]) continue; for(int i=0; i<=2*n; i++){ if(nowedp[licz]>mini){ nowedp[licz] = mini; useless[licz]=1; } else{ mini = nowedp[licz]; } mini+=cost; licz+=mas; licz%=m; if(odw[licz]) break; odw[licz] = 1; } } } for(int i=0; i<m; i++){ if(nowedp[i]>=1e18) cout << "-1\n"; else cout << nowedp[i]<<"\n"; } } |