#include <iostream>
#include <vector>
#include <string>
using namespace std;
const int INF = 1e9;
int main() {
cout << "=============================================\n";
cout << " OPTIMASI PENGIRIMAN PAKET DRONE (DP)\n";
cout << "=============================================\n\n";
// INPUT DATA
vector<int> jarak = {2, 3, 3, 4, 5, 6};
int K = 7;
int N = jarak.size();
cout << "Jumlah pelanggan: " << N << endl;
cout << "Kapasitas baterai drone: " << K << endl;
cout << "Jarak pelanggan: ";
for(int d : jarak) cout << d << " ";
cout << "\n\n";
// PRECOMPUTE SUBSET VALID
int TOTAL = 1 << N;
vector<int> subsetValid;
vector<int> subsetJarak(TOTAL, 0);
for(int mask = 1; mask < TOTAL; mask++) {
int sum = 0;
for(int i = 0; i < N; i++) {
if(mask & (1 << i)) {
sum += jarak[i];
}
}
subsetJarak[mask] = sum;
if(sum <= K) {
subsetValid.push_back(mask);
}
}
// DP BITMASK
vector<int> dp(TOTAL, INF);
vector<int> prevMask(TOTAL, -1);
vector<int> paketDipilih(TOTAL, -1);
dp[0] = 0;
for(int mask = 0; mask < TOTAL; mask++) {
if(dp[mask] == INF) continue;
for(int sMask : subsetValid) {
int newMask = mask | sMask;
if(dp[newMask] > dp[mask] + 1) {
dp[newMask] = dp[mask] + 1;
prevMask[newMask] = mask;
paketDipilih[newMask] = sMask;
}
}
}
int finalMask = TOTAL - 1;
//HASIL
cout << "Jumlah perjalanan minimal = " << dp[finalMask] << "\n\n";
cout << "Rincian Pengiriman:\n";
cout << "-------------------\n";
vector<int> urutan;
int mask = finalMask;
while(mask != 0) {
urutan.push_back(paketDipilih[mask]);
mask = prevMask[mask];
}
int trip = 1;
for(int i = urutan.size()-1; i >= 0; i--) {
int sMask = urutan[i];
cout << "Perjalanan " << trip++ << " : ";
int totalJ = 0;
for(int j = 0; j < N; j++) {
if(sMask & (1 << j)) {
cout << "Pelanggan-" << (j+1) << "(jarak " << jarak[j] << ") ";
totalJ += jarak[j];
}
}
cout << " -> Total jarak: " << totalJ << endl;
}
cout << "\nSemua paket berhasil dikirim!\n";
cout << "=============================================\n";
return 0;
}