Advertisement
Uwwan

Knapsack

Nov 13th, 2022
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 4.44 KB | None | 0 0
  1. fun bagPacking(treasures: Map<String, Pair<Int, Int>>, capacity: Int): Set<String> {// по веритикали- список предметов
  2.     if (treasures.size == 0) return emptySet() // вырожденный случай
  3.     val table: Array<Array<Pair<Int, MutableSet<String>>>> =
  4.         Array(treasures.size) {
  5.             Array<Pair<Int, MutableSet<String>>>(capacity + 1) { Pair(0, mutableSetOf()) }
  6.         } // по горизонтали - Вес
  7.     // а внутри Пара - Мак. сумма, к этому весу, если взять все элементы от 0 до этого, + Множество названий пердметов,
  8.     // которые мы взяли для такой суммы
  9.     // - ? Почему size:capacity + 1 ? - потому что нумерация начинается с нуля, и мы будем считать возможным
  10.     // что существует артефакт с нулевой массой, его кстати, надо брать в любом случае, как и все те с отрицательной
  11.     // массой (хорошо, что хоть цена не отрицательная)
  12.  
  13.     var i = 0
  14.     for ((artifact, stats) in treasures) {//stats - это пара из Веса и Цены
  15.         val weight = stats.first
  16.         val price = stats.second
  17.         for (j in 0 until capacity + 1) {
  18.             if (i == treasures.size) break
  19.             //print(table[i][j])
  20.             //print(" || ")
  21.             // Ячейка [%artifact%][Вес], в ней хранится Пара значений - $$ Доллары за арт $$ и Множество собраных артов
  22.  
  23.             // У нас есть выбор: мы можем брать артефакт, или нет
  24.  
  25.             // Если вес артефакта превышает заданный вес j, то мы не берем артефакт. А значит максимальное значение
  26.             // с таким же макс весом j и с набором артефактов, включающих i-ый** , берется из строчки выше
  27.             //**будем считать, что элементы пронумерованы по порядку, в котором их достает итератор.
  28.             if (weight > j) table[i][j] = if (i >= 1) table[i - 1][j] else Pair(0, mutableSetOf())
  29.             // Иначе, если артефакт "подъемный", то мы стоим перед выбором: Брать или не брать? Вот в чем вопрос.
  30.             // чтобы получить максимальное значение,мы"скормим maxOf"(на самом деле надо сравнить) значения с и без арта
  31.             // казалось бы, надо всегда брать арт-к, но только мы сравниваем значение такое, чтобы вес арта поместился,
  32.             // т.е по адресу [i-1][j- (Вес Артефакта) ]
  33.             else {
  34.                 if (i < 1) {
  35.                     table[i][j] = Pair(price, mutableSetOf(artifact))
  36.                 } else {
  37.  
  38.                     /*       if (table[i - 1][j].first == table[i][j - weight].first + price) { //Вырожденный случай
  39.                                table[i][j] = Pair(
  40.                                    table[i - 1][j].first + price,
  41.                                    table[i - 1][j].second.plus(artifact).toMutableSet()
  42.                                )}*/
  43.                     if (table[i - 1][j].first <= table[i - 1][j - weight].first + price) {
  44.                         table[i][j] = Pair(
  45.                             table[i - 1][j - weight].first + price,
  46.                             table[i - 1][j - weight].second.plus(artifact).toMutableSet()
  47.                         )
  48.                     } else table[i][j] = table[i - 1][j]
  49.                 }
  50.             }
  51.         }
  52.         //println()
  53.         i++
  54.     }
  55.     //ans = table[allElements][maxWeight].second //Ответ я вычислю, проходясь по таблице, основываясь на
  56.     return table[treasures.size - 1][capacity].second
  57. }
  58. //Worst case scenario:
  59. /*assertEquals(
  60.     setOf("1","0"),
  61.     lesson5.task1.bagPacking(
  62.         mapOf("1" to (1 to 1), "0" to (1 to 1)),
  63.         2
  64.     )
  65. )*/
  66.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement