#include <algorithm>
#include <iostream>
#include <span>
#include <stdexcept>
#include <vector>
int min_coins(std::span<const int> coins, int amount) {
    if (amount < 0 || amount > 10000) throw std::invalid_argument("amount range");
    for (const int c : coins) if (c <= 0) throw std::invalid_argument("positive coins required");
    const int impossible = amount + 1;
    std::vector<int> dp(static_cast<std::size_t>(amount) + 1, impossible);
    dp[0] = 0;
    for (int s = 1; s <= amount; ++s)
        for (const int c : coins)
            if (c <= s) dp[static_cast<std::size_t>(s)] = std::min(dp[static_cast<std::size_t>(s)], dp[static_cast<std::size_t>(s-c)] + 1);
    return dp[static_cast<std::size_t>(amount)] == impossible ? -1 : dp[static_cast<std::size_t>(amount)];
}
int main() {
    const std::vector<int> coins{1,3,4}, even{2};
    if (min_coins(coins, 6) != 2 || min_coins(even, 3) != -1 || min_coins(coins, 0) != 0) return 1;
    std::cout << "coins=" << min_coins(coins, 6) << " impossible=" << min_coins(even, 3)
              << " zero=" << min_coins(coins, 0) << '\n';
}
