#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef __int128 i128; const ll INF = 213721372137213722; i128 INF2 = 21372137213722; void wypisz(i128 x){ if (x < INF){ ll x2 = x; cout<<x2<<"\n"; return; } string wy = ""; while (x){ wy += '0'+x%10; x /= 10; } reverse(wy.begin(),wy.end()); cout<<wy<<"\n"; } signed main(){ ios_base::sync_with_stdio(0); cin.tie(0); INF2 = INF2*INF2; ll i; ll n,k,m; cin>>n>>k>>m; vector<pair<ll,ll> > wkolorze[k+1]; for (i = 0; i < n; i++){ ll a,b,c; cin>>a>>b>>c; wkolorze[a].push_back({b,c}); } //Liczymy możliwe pojedyncze ruchy ll dp[m][2]; for (i = 0; i < m; i++) dp[i][0] = INF; dp[0][0] = 0; for (ll kolor = 1; kolor <= k; kolor++){ for (i = 0; i < m; i++) dp[i][kolor%2] = INF; for (auto j : wkolorze[kolor]){ for (i = 0; i < m; i++){ dp[(i+j.first)%m][kolor%2] = min(dp[(i+j.first)%m][kolor%2],dp[i][(kolor+1)%2]+j.second); } } } //Liczymy "wielokrotnosci" - pewnie mozna w O(m) lub O(m log m) for (i = 0; i < m; i++){ if (dp[i][k%2] == INF) continue; for (ll j = 1; j <= m; j++){ if (j*dp[i][k%2] >= INF) break; dp[(j*i)%m][k%2] = min(dp[(j*i)%m][k%2],j*dp[i][k%2]); } } //robimy drugi plecak, kazda wartosc wystepuje maks raz i128 dp2[m][2]; for (i = 0; i < m; i++) dp2[i][1] = INF2; dp2[0][1] = 0; for (int j = 0; j < m; j++){ for (i = 0; i < m; i++) dp2[i][j%2] = dp2[i][(j+1)%2]; if (dp[j][k%2] == INF) continue; for (i = 0; i < m; i++){ if (dp2[i][(j+1)%2] == INF2) continue; dp2[(i+j)%m][j%2] = min(dp2[(i+j)%m][j%2],dp2[i][(j+1)%2]+(i128)dp[j][k%2]); } } for (i = 0; i < m; i++){ if (dp2[i][(m+1)%2] == INF2) cout<<"-1\n"; else wypisz(dp2[i][(m+1)%2]); } 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 | #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef __int128 i128; const ll INF = 213721372137213722; i128 INF2 = 21372137213722; void wypisz(i128 x){ if (x < INF){ ll x2 = x; cout<<x2<<"\n"; return; } string wy = ""; while (x){ wy += '0'+x%10; x /= 10; } reverse(wy.begin(),wy.end()); cout<<wy<<"\n"; } signed main(){ ios_base::sync_with_stdio(0); cin.tie(0); INF2 = INF2*INF2; ll i; ll n,k,m; cin>>n>>k>>m; vector<pair<ll,ll> > wkolorze[k+1]; for (i = 0; i < n; i++){ ll a,b,c; cin>>a>>b>>c; wkolorze[a].push_back({b,c}); } //Liczymy możliwe pojedyncze ruchy ll dp[m][2]; for (i = 0; i < m; i++) dp[i][0] = INF; dp[0][0] = 0; for (ll kolor = 1; kolor <= k; kolor++){ for (i = 0; i < m; i++) dp[i][kolor%2] = INF; for (auto j : wkolorze[kolor]){ for (i = 0; i < m; i++){ dp[(i+j.first)%m][kolor%2] = min(dp[(i+j.first)%m][kolor%2],dp[i][(kolor+1)%2]+j.second); } } } //Liczymy "wielokrotnosci" - pewnie mozna w O(m) lub O(m log m) for (i = 0; i < m; i++){ if (dp[i][k%2] == INF) continue; for (ll j = 1; j <= m; j++){ if (j*dp[i][k%2] >= INF) break; dp[(j*i)%m][k%2] = min(dp[(j*i)%m][k%2],j*dp[i][k%2]); } } //robimy drugi plecak, kazda wartosc wystepuje maks raz i128 dp2[m][2]; for (i = 0; i < m; i++) dp2[i][1] = INF2; dp2[0][1] = 0; for (int j = 0; j < m; j++){ for (i = 0; i < m; i++) dp2[i][j%2] = dp2[i][(j+1)%2]; if (dp[j][k%2] == INF) continue; for (i = 0; i < m; i++){ if (dp2[i][(j+1)%2] == INF2) continue; dp2[(i+j)%m][j%2] = min(dp2[(i+j)%m][j%2],dp2[i][(j+1)%2]+(i128)dp[j][k%2]); } } for (i = 0; i < m; i++){ if (dp2[i][(m+1)%2] == INF2) cout<<"-1\n"; else wypisz(dp2[i][(m+1)%2]); } return 0; } |