JirR02 c71d2e026f Exercise 7
Added Exercise 7 to Repository
2025-04-07 08:56:57 +02:00
..
2025-04-07 08:56:57 +02:00

Task 4: [Exam 2022.08 (ITET/MATH/PHYS/RW)] Mini-Knapsack

Note

I don't know if we have to solve this task recursively or not. It is in the topic of week but the task does not state this explicitly.

Task Description

As part of a promotion of the local supermarket, you are allowed to get exactly two items for free. You want to maximize the value of the items you take, but you need to take the weight limit of your backpack into account.

You get two integer vectors, one with the value of every item, and one with its weight. Return the maximum value that you can get by choosing exactly 2 different items from the supermarket.

Function

Implement the function best_two_elements in functions.h according to its pre- and postconditions.

Rules:

  • The functions must satisfy their respective postconditions.
  • You are not allowed to change the function signatures.
  • You are not allowed to use additional libraries.

Hint:

  • You do not need to check the pre- and postconditions (no asserts necessary).

Solution

#pragma once

#include <vector>

using vec = std::vector<int>;

// PRE:   The vector "weights" at position i contains the weight of element
// i.
//        The vector "values" at position i contains the value of element i.
//        The vectors have the same size and always contain at least two
//        items. The value and weight of every item is > 0.
//
// POST:  Returns the sum of the value of the two items that have the most
// value,
//        while the sum of their weight is at most `weight_limit`.
//        It is not allowed to pick only one item.
//        It is also not allowed to pick an item twice, but two different
//        items must be chosen. If there are no two items that can be chosen
//        (due to exceeding weight), return 0.
//
// Example:
//  * weights: [1, 2, 2], values: [3, 1, 9], weight_limit: 3  ~~> 12;

void recursion1(int &value, int count1, int count2, const vec &values,
                const vec &weights, int weight_limit) {
  if (count2 == int(values.size()))
  return;

  if (int((values.at(count1)) + int(values.at(count2))) >= value &&
    (int(weights.at(count1)) + int(weights.at(count2))) <= weight_limit)
  value = int(values.at(count1)) + int(values.at(count2));

  recursion1(value, count1, count2 + 1, values, weights, weight_limit);
}

void recursion2(int &value, int count1, const vec &values, const vec &weights,
                int weight_limit) {
  if (count1 == (int(values.size()) - 1))
  return;

  recursion1(value, count1, count1 + 1, values, weights, weight_limit);
  recursion2(value, count1 + 1, values, weights, weight_limit);
}

int best_two_elements(const vec &values, const vec &weights, int weight_limit) {
  int value = 0;

  if (values.size() == weights.size() && values.size() >= 2 &&
    weights.size() >= 2) {
    recursion2(value, 0, values, weights, weight_limit);
  }

  return value;
}