akela43

knack

Jun 1st, 2020
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. Задача о рюкзаке на c++
  3. Кол-во предметов: 1900, диапазон весов: 29 — макс вес., 1 — мин вес. Веса распределяются равномерно (вероятность равная для любого веса). Стоимость предметов — от 1 до 2 (double) — равновероятно. (т. е. Все рандомить и переводить даблом). Макс вес — 500. Найти такую комбинацию предметов, наименьшую по весу и наибольшую по стоимости, чтобы помещалась в рюкзак.
  4. И выводить именно набор предметов
  5. Напишите пожалуйста код на c++
  6. */
  7. #include <vector>
  8. #include <algorithm>
  9. #include <iostream>
  10. #include <random>
  11. using  TVWeight = std::vector <int>;
  12. using  TVCost = std::vector <double>;
  13.  
  14. /**
  15.  * @brief knack
  16.  * @param K емкость рюкзака
  17.  * @param W вектор с весами предметов
  18.  * @param C вектор со стоимостями
  19.  * @param res указатель на вектор, для возврата индексов предметов
  20.  * @return максимальная полученная стоимость
  21.  */
  22. double knack (int K, const TVWeight & W, const TVCost & C,
  23.               std::vector<int> & res) {
  24.     int N = W.size(); // количество предметов
  25.     std::vector<TVCost> F(N + 1, TVCost (K + 1, 0));
  26.     for (auto i = 1; i < N + 1; ++i)
  27.         for (auto k = 1; k < K + 1; ++k)
  28.             if (k >= W[i - 1])
  29.                 F[i][k] = std::max(F[i - 1][k], F[i - 1][k - W[i - 1]] + C[i - 1]);
  30.             else
  31.                 F[i][k] = F[i - 1][k];
  32.     for (auto i = N, k = K; i > 0; --i) {
  33.         if (F[i][k] != F[i -1][k]) {
  34.             res.push_back(i - 1);
  35.             k -= W[i - 1];
  36.         }
  37.     }
  38.     return F[N][K];
  39. }
  40. int main() {
  41.     int n = 1900;
  42.     std::vector<int> W (n);
  43.     std::vector<double> C (n);
  44.     std::mt19937 gen{ std::random_device()()};
  45.     std::uniform_int_distribution<> dis(1, 29);
  46.     std::uniform_real_distribution<> dis2(1.0, 2.0);
  47.     auto rand1 = [&] { return dis(gen); };
  48.     auto rand2 = [&] { return dis2(gen); };
  49.     generate(W.begin(), W.end(), rand1);
  50.     generate(C.begin(), C.end(), rand2);
  51.  
  52.     std::vector<int> res;
  53.     double m = knack(500, W, C, res);
  54.     for (auto i: res)
  55.         std::cout << i << " "; // индекс предмета
  56.     std::cout << "\nresult: " << m;
  57.  
  58. }
Add Comment
Please, Sign In to add comment