#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; } |
English