<?php

error_reporting(-1);

$bills = Array(10, 50, 100, 200, 500, 1000, 2000); // какие виды банкнот есть
$countOfBills = count($bills); // кол-во видов банкнот
$needleMoney = 6600; // сумма которую надо выдать

// 1 часть алгоритма
$INF = PHP_INT_MAX; //Бесконечность
$F = Array(); //Массив вида: Требуемая сумма => Минимальное количество купюр для её выдачи
$F[0] = 0; //Ноль гривен выдать нельзя

for ($i = 1; $i <= $needleMoney; ++$i) { //Флажок i идет от единицы до суммы, которую необходимо выдать

    $F[$i] = $INF; //По умолчанию считаем что вывод невозможен
    for ($j = 0; $j < $countOfBills; ++$j) { //Массив проходит по всем банкнотам, его флажок j служит ключем для массива с банкнотами
        if ($i >= $bills[$j] && $F[$i - $bills[$j]] + 1 < $F[$i]) { /*Если $i больше чем текущая банкнота и
            F[$i-ТекущаяБанкнота] +1 меньше чем количество банкнот для $i */
            $F[$i] = $F[$i - $bills[$j]] + 1; //Тогда определяется новое количество банкнот для $i, оно равно F[$i-ТекущаяБанкнота] +1
        }
    }
}

// 2 часть алгоритма
if ($F[$needleMoney] == $INF) { //Если количество купюр для выдачи необходимой суммы бесконечно
    echo "Требуемую сумму выдать невозможно\r\n"; // Выводим сообщение об этом
} else { //В другом случае
    while ($needleMoney > 0) { //Пока необходимая сумма больше нуля
        for ($i = 0; $i < $countOfBills; ++$i) { //Цикл фор, в котором перебираются номиналы
            if ($F[$needleMoney - $bills[$i]] == $F[$needleMoney] - 1) { //Если F[Необходимая сумма МИНУС купюра данного номинала == F[Необходимая сума]-1 ]
                echo $bills[$i] . " "; //Выводим эту купюру
                $needleMoney -= $bills[$i]; //Минусуем от необходимой суммы купюру
                break; //Конец
            }
        }
    }
}