// Una sola fila: de mayor a menor funciona; de menor a mayor resuelve otro problema.
#include <iomanip>
#include <iostream>
#include <vector>

#include "knapsack.h"

namespace {

void print_row(const std::vector<long long>& row) {
    for (long long value : row) std::cout << std::setw(3) << value;
    std::cout << '\n';
}

}  // namespace

int main() {
    const Item item = {2, 3};
    const std::size_t capacity = 6;
    std::cout << "Un solo objeto (peso 2, valor 3), capacidad 6\n";

    std::cout << "\nDe mayor a menor:\n         c:  0  1  2  3  4  5  6\n";
    std::vector<long long> row(capacity + 1, 0);
    for (std::size_t c = capacity + 1; c-- > item.weight;) {
        row[c] = std::max(row[c], item.value + row[c - item.weight]);
        std::cout << "tras c = " << c << ":";
        print_row(row);
    }

    std::cout << "\nDe menor a mayor:\n         c:  0  1  2  3  4  5  6\n";
    row.assign(capacity + 1, 0);
    for (std::size_t c = item.weight; c <= capacity; c++) {
        row[c] = std::max(row[c], item.value + row[c - item.weight]);
        std::cout << "tras c = " << c << ":";
        print_row(row);
    }

    const std::vector<Item> items = {{2, 3}, {3, 4}, {4, 5}, {5, 8}};
    const std::size_t big = 9;
    std::cout << "\nLos objetos del ejemplo, capacidad 9\n";
    std::cout << "  tabla completa:      " << knapsack_table(items, big).back()[big] << '\n';
    std::cout << "  fila, mayor a menor: " << knapsack_one_row(items, big) << '\n';
    std::cout << "  fila, menor a mayor: " << knapsack_one_row_ascending(items, big) << '\n';
    std::cout << "  sin límite de copias: " << unbounded_knapsack(items, big) << '\n';
}
