// Pakowanie.cpp : Defines the entry point for the console application. // #include <iostream> #include <vector> #include <algorithm> using namespace std; int najmniej_plecakow (long long int suma_gratow, const vector<int> & plecaki) { vector<int>::const_iterator it = plecaki.begin(); int ile = 0; while (suma_gratow > 0 && it != plecaki.end()) { suma_gratow -= *it; ++it; ile++;} return ile; } int najwiecej_plecakow (const vector<int> & graty, vector<int> plecaki) { int ile_plecakow = 0; for (int ii=0; ii < graty.size(); ii++) { int jj = 0; while (jj < plecaki.size() && graty[ii] > plecaki[jj]) jj++; if (jj == plecaki.size()) // sprawdzono wszystkie plecaki i zaden nie ma odpowiedniego rozmiaru return -1; plecaki[jj] -= graty[ii]; // wrzucamy grat do pierwszego pasujacego plecaka, pojemnosc plecaka ulega zmniejszeniu ile_plecakow = max(ile_plecakow, jj+1); } return ile_plecakow ; } int pakowanie (vector<int>::iterator graty_start, vector<int>::iterator graty_stop, const vector<int> & plecaki, vector<int> & zajete, int min_plecakow, int max_plecakow) { // graty_start, graty_stop - rozpatrywany przedzial tablicy gratow do upchniecia w plecakach // plecaki - maksymalne pojemnoesci kolejnych plecakow // zajete - zajete miejsce w kolejnych plecakach - domyslnie na poczotku wektor zer o dlugosci wektora plecaki // min_plecakow - min niezbedna liczba plecakow, jesli znaleziono rozw ktore miesci sie w tej liczbie - natychmiastowe przerwanie wyszukiwania //int ile = plecaki.size(); // wariant pesymistyczny - zuzyjemy wszystkie plecaki, dalej sprawdzamy czy da sie lepiej if (graty_start == graty_stop) // nie ma wiecej gratow do zapakowania { int ile = 0; for (int ii = 0; ii < plecaki.size(); ii++) if (zajete[ii] > 0) // zliczanie uzywanych plecakow ile++ ; return ile; } for (int ii = 0; ii < max_plecakow - 1; ii++) // sprawdzamy bez ostatniego (najmniejszego) plecaka - bo szukamy kombinacji plecakow mniejszej niz plecaki.size() { if (*graty_start <= plecaki[ii] - zajete[ii]) // pierwszy najwiekszy grat miesci sie w ii-tym plecaku { zajete[ii] += *graty_start; // wrzucamy pierwszy grat do ii-tego plecaka i rozwiazujemy podproblem n-1 gratow max_plecakow = min(max_plecakow, pakowanie (graty_start +1, graty_stop, plecaki, zajete, min_plecakow, max_plecakow)); zajete[ii] -= *graty_start; // wyjmujemy pierwszy grat z ii-tego plecaka i probujemy zmiescic go w innych if (max_plecakow == min_plecakow) return min_plecakow; // lepiej juz sie nie da zrobic! } } return max_plecakow; } int main() { int ile_gratow, ile_plecakow; cin >> ile_gratow >> ile_plecakow; vector<int> graty(ile_gratow,0), plecaki(ile_plecakow,0); long long int suma_gratow=0; for (int ii=0; ii< ile_gratow; ii++) { cin >> graty[ii]; suma_gratow += graty[ii]; } for (int ii=0; ii < ile_plecakow; ii++) cin >> plecaki[ii]; // sortowanie gratow i plecakow w kolejnosci od najwiekszych do najmniejszych sort(graty.begin(), graty.end(), [](int a, int b){return a>b;}); sort(plecaki.begin(), plecaki.end(), [](int a, int b){return a>b;}); if (plecaki.size() > graty.size()) plecaki.erase(plecaki.begin() + graty.size(), plecaki.end()); // poszukiwana ilosc plecakow miesci sie w granicach: int min_plecakow = najmniej_plecakow(suma_gratow, plecaki); // minimalna liczba plecakow niezbedna do przeniesienia wszystkich gratow - przy zalozeniu 100% wypelnienia plecakow int max_plecakow = najwiecej_plecakow(graty, plecaki); // ilosc plecakow potrzebna do zapakowania gratow algorytmem: wrzuc pierwszy najwiekszy grat do najwiekszego plecaka w ktorym sie zmiesci if (max_plecakow == -1) // plecaki za male zeby pomiescic wieksze graty! {cout << "NIE"; return 0;} if (min_plecakow==max_plecakow) { cout << max_plecakow; return 0; } if (plecaki.size() > max_plecakow) plecaki.erase(plecaki.begin() + max_plecakow, plecaki.end()); // pozbywamy sie niepotrzebnych plecakow // szukanie lepszego sposobu zapakowania - zuzywajacego mniej placakow niz max_plecakow vector<int> zajete(plecaki.size(), 0); int wynik = pakowanie (graty.begin(), graty.end(), plecaki, zajete, min_plecakow, max_plecakow); cout << wynik; //cout << min_plecakow << ' ' << max_plecakow << ' ' << ile_plecakow; 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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | // Pakowanie.cpp : Defines the entry point for the console application. // #include <iostream> #include <vector> #include <algorithm> using namespace std; int najmniej_plecakow (long long int suma_gratow, const vector<int> & plecaki) { vector<int>::const_iterator it = plecaki.begin(); int ile = 0; while (suma_gratow > 0 && it != plecaki.end()) { suma_gratow -= *it; ++it; ile++;} return ile; } int najwiecej_plecakow (const vector<int> & graty, vector<int> plecaki) { int ile_plecakow = 0; for (int ii=0; ii < graty.size(); ii++) { int jj = 0; while (jj < plecaki.size() && graty[ii] > plecaki[jj]) jj++; if (jj == plecaki.size()) // sprawdzono wszystkie plecaki i zaden nie ma odpowiedniego rozmiaru return -1; plecaki[jj] -= graty[ii]; // wrzucamy grat do pierwszego pasujacego plecaka, pojemnosc plecaka ulega zmniejszeniu ile_plecakow = max(ile_plecakow, jj+1); } return ile_plecakow ; } int pakowanie (vector<int>::iterator graty_start, vector<int>::iterator graty_stop, const vector<int> & plecaki, vector<int> & zajete, int min_plecakow, int max_plecakow) { // graty_start, graty_stop - rozpatrywany przedzial tablicy gratow do upchniecia w plecakach // plecaki - maksymalne pojemnoesci kolejnych plecakow // zajete - zajete miejsce w kolejnych plecakach - domyslnie na poczotku wektor zer o dlugosci wektora plecaki // min_plecakow - min niezbedna liczba plecakow, jesli znaleziono rozw ktore miesci sie w tej liczbie - natychmiastowe przerwanie wyszukiwania //int ile = plecaki.size(); // wariant pesymistyczny - zuzyjemy wszystkie plecaki, dalej sprawdzamy czy da sie lepiej if (graty_start == graty_stop) // nie ma wiecej gratow do zapakowania { int ile = 0; for (int ii = 0; ii < plecaki.size(); ii++) if (zajete[ii] > 0) // zliczanie uzywanych plecakow ile++ ; return ile; } for (int ii = 0; ii < max_plecakow - 1; ii++) // sprawdzamy bez ostatniego (najmniejszego) plecaka - bo szukamy kombinacji plecakow mniejszej niz plecaki.size() { if (*graty_start <= plecaki[ii] - zajete[ii]) // pierwszy najwiekszy grat miesci sie w ii-tym plecaku { zajete[ii] += *graty_start; // wrzucamy pierwszy grat do ii-tego plecaka i rozwiazujemy podproblem n-1 gratow max_plecakow = min(max_plecakow, pakowanie (graty_start +1, graty_stop, plecaki, zajete, min_plecakow, max_plecakow)); zajete[ii] -= *graty_start; // wyjmujemy pierwszy grat z ii-tego plecaka i probujemy zmiescic go w innych if (max_plecakow == min_plecakow) return min_plecakow; // lepiej juz sie nie da zrobic! } } return max_plecakow; } int main() { int ile_gratow, ile_plecakow; cin >> ile_gratow >> ile_plecakow; vector<int> graty(ile_gratow,0), plecaki(ile_plecakow,0); long long int suma_gratow=0; for (int ii=0; ii< ile_gratow; ii++) { cin >> graty[ii]; suma_gratow += graty[ii]; } for (int ii=0; ii < ile_plecakow; ii++) cin >> plecaki[ii]; // sortowanie gratow i plecakow w kolejnosci od najwiekszych do najmniejszych sort(graty.begin(), graty.end(), [](int a, int b){return a>b;}); sort(plecaki.begin(), plecaki.end(), [](int a, int b){return a>b;}); if (plecaki.size() > graty.size()) plecaki.erase(plecaki.begin() + graty.size(), plecaki.end()); // poszukiwana ilosc plecakow miesci sie w granicach: int min_plecakow = najmniej_plecakow(suma_gratow, plecaki); // minimalna liczba plecakow niezbedna do przeniesienia wszystkich gratow - przy zalozeniu 100% wypelnienia plecakow int max_plecakow = najwiecej_plecakow(graty, plecaki); // ilosc plecakow potrzebna do zapakowania gratow algorytmem: wrzuc pierwszy najwiekszy grat do najwiekszego plecaka w ktorym sie zmiesci if (max_plecakow == -1) // plecaki za male zeby pomiescic wieksze graty! {cout << "NIE"; return 0;} if (min_plecakow==max_plecakow) { cout << max_plecakow; return 0; } if (plecaki.size() > max_plecakow) plecaki.erase(plecaki.begin() + max_plecakow, plecaki.end()); // pozbywamy sie niepotrzebnych plecakow // szukanie lepszego sposobu zapakowania - zuzywajacego mniej placakow niz max_plecakow vector<int> zajete(plecaki.size(), 0); int wynik = pakowanie (graty.begin(), graty.end(), plecaki, zajete, min_plecakow, max_plecakow); cout << wynik; //cout << min_plecakow << ' ' << max_plecakow << ' ' << ile_plecakow; return 0; } |