Вариант через динамическое программирование.
function bankomat(sum, coins, maxCC) {
const full = coins.reduce((sum, c) => sum + c * maxCC, 0);
if (full < sum) return -1;
const dp = Array.from({length: sum + 1}, () => ({
count: full + 1,
coins: {},
}));
coins.sort((a, b) => a - b);
dp[0].count = 0;
for (let i = 1; i <= sum; ++i) {
const item = dp[i];
let optCoin = 0;
for (let j = 0; j < coins.length; ++j) {
const coin = coins[j];
if (coin > i) break;
const prev = dp[i - coin];
if (item.count > prev.count + 1 && (prev.coins[coin] || 0) < maxCC) {
item.count = prev.count + 1;
optCoin = coin;
}
}
if (optCoin) {
const prev = dp[i - optCoin];
item.coins = {
...prev.coins,
[optCoin]: (prev.coins[optCoin] || 0) + 1
};
}
}
if (dp[sum].count > full) {
return 0;
}
const arr = [];
Object.keys(dp[sum].coins).forEach((coin) => {
const c = dp[sum].coins[coin];
for (let i = 0; i < c; ++i) {
arr.push(Number(coin));
}
});
return arr;
}
console.log(bankomat(100, [11, 20, 30, 40, 12, 99], 2)); // [20, 40, 40]