<?php
header("Content-Type: text/plain");
/* Задача про банкомат
* пытаемся выдать 6600 р.
* число банкнот: 1 по 5000, 4 по 2000, 1 по 500, 3 по 200
*/
// Требуемая сумма
$amount = 6600;
// Ответ: сумма размены, номиналы и их количество
$ans = array ('amount' => $amount);
// Номиналы банкнот, количество
1 => Array ('value' => 200, 'quantity' => 3), 2 => Array ('value' => 500, 'quantity' => 1), 3 => Array ('value' => 2000, 'quantity' => 4), 4 => Array ('value' => 5000, 'quantity' => 1) );
// Массив в котором мы храним результат вычислений $results[$numBill][$currentAmount]
// Частичное заполнение массива
// Для всех сумм банкнотой 0 размен не ввозможен (INF)
for ($currentAmount = 0; $currentAmount <= $amount; $currentAmount++) {
$results[0][$currentAmount] = INF;}
// Если просят разменять сумму 0, гордо протягиваем пустую ладонь (0 банкнот).
for ($numBill = 0; $numBill <= count($bills); $numBill++) { $results[$numBill][0] = 0;
}
// $currentAmount - текущая сумма, которую нужно выдать, увеличиваем от 1 до требуемой $amount
for($currentAmount = 1; $currentAmount <= $amount; $currentAmount++) {
// Перебираем все номиналы банкнот
foreach ($bills as $numBill => $bill) {
// По умолчанию, текущую сумму можно выдать банкнотой предыдущего номинала.
$results[$numBill][$currentAmount] = $results[$numBill-1][$currentAmount];
// Есть ли банкноты текущего номинала и текущую сумму можно разменять текущим номиналом
if ($bill['quantity']>0 && $currentAmount >= $bill['value']) {
/* Перебираем количество банкнот текущего номинала
от минимально требуемого (или того что есть) до 1 */
for ($minQuant=min($bill['quantity'], intval(floor($currentAmount/$bill['value']))); $minQuant >= 1; $minQuant--) {
/* Выбираем минимальное количество банкнот для размена между данной банкнотой и предыдущей
если сумму меняем текущей банкнотой, то записываем количество банкнот
для данного номинала и количество монет предыдущих номиналов, для размена остатка суммы */
$results[$numBill][$currentAmount] = min($results[$numBill][$currentAmount], $results[$numBill-1][$currentAmount - $minQuant * $bill['value']] + $minQuant); }
}
}
}
// Ф-я считает банкноты для размены требуемой суммы для Анона
// аргументы: массив с результатом, банкноты (номинал/кол-во), кол-во номиналов, сумма для выдачи, ответ
function findAns($results, $bills, $numBill, $amount, $ans) {
while ($results[$numBill][$amount] != 0) {
/* если для размена текущей суммы количество банкнот прошлого номинала нужно столько же,
то переходим к предыдущему номиналу */
if ($results[$numBill-1][$amount] == $results[$numBill][$amount]) {
$numBill--;
/* если текущую сумму можно несколько раз выдать текущей банкнотой, делаем это,
и добавляем текущую банкноту к результату и уменьшаем сумму выдачи на текущий номинал*/
} elseif ($results[$numBill][$amount] >= $results[$numBill][$amount-$bills[$numBill]['value']]) {
if (isset($ans[$bills[$numBill]['value']])) { $ans[$bills[$numBill]['value']]++;
} else {
$ans[$bills[$numBill]['value']]=1;
}
$amount -= $bills[$numBill]['value'];
/* если остаток текущей суммы, после размена текущей банкнотой, можно выдать только
банкнотой предыдущего номинала, так тому и быть, + 1 к результату, переходим к
предыдущему номиналу и уменьшаем сумму выдачи на текущий номинал */
} else {
if (isset($ans[$bills[$numBill]['value']])) { $ans[$bills[$numBill]['value']]++;
} else {
$ans[$bills[$numBill]['value']]=1;
}
$numBill--;
$amount -= $bills[$numBill]['value'];
}
}
printAns ($ans); // отправляем ответ на печать
}
// Проверяем существует ли ответ для данной суммы, зовем findAns или ругаемся.
function checkAns($results, $bills, $numBill, $amount, $ans) {
if ($results[$numBill][$amount]==INF) {
$ans['result']=NULL;
printAns ($ans); // отправляем ответ на печать
} else {
$ans = findAns($results, $bills, $numBill, $amount, $ans);
}
}
// Выводим результат
function printAns ($ans) {
echo "Сумма: {$ans['amount']}\n";
if ($ans['result']=NULL) {
echo "Требуемую сумму выдать невозможно";
} else {
echo "Выдача возможна, число купюр:\n";
foreach($ans as $billValue => $quantity) {
if ($billValue!=0) {
echo "{$quantity}x{$billValue}" . " ";
}
}
}
}
// Запускаем проверку
checkAns
($results, $bills, count($bills), $amount, $ans);?>
PD9waHAKaGVhZGVyKCJDb250ZW50LVR5cGU6IHRleHQvcGxhaW4iKTsKbWJfaW50ZXJuYWxfZW5jb2RpbmcoJ3V0Zi04Jyk7CgovKiAg0JfQsNC00LDRh9CwINC/0YDQviDQsdCw0L3QutC+0LzQsNGCCiAqICDQv9GL0YLQsNC10LzRgdGPINCy0YvQtNCw0YLRjCA2NjAwINGALgogKiAg0YfQuNGB0LvQviDQsdCw0L3QutC90L7RgjogMSDQv9C+IDUwMDAsIDQg0L/QviAyMDAwLCAxINC/0L4gNTAwLCAzINC/0L4gMjAwCiAqLwoKLy8g0KLRgNC10LHRg9C10LzQsNGPINGB0YPQvNC80LAgCiRhbW91bnQgPSA2NjAwOwoKLy8g0J7RgtCy0LXRgjog0YHRg9C80LzQsCDRgNCw0LfQvNC10L3Riywg0L3QvtC80LjQvdCw0LvRiyDQuCDQuNGFINC60L7Qu9C40YfQtdGB0YLQstC+IAokYW5zID0gYXJyYXkgKCdhbW91bnQnID0+ICRhbW91bnQpOyAKCi8vINCd0L7QvNC40L3QsNC70Ysg0LHQsNC90LrQvdC+0YIsINC60L7Qu9C40YfQtdGB0YLQstC+CiRiaWxscyA9IEFycmF5ICgKICAgICAgICAgICAgICAgIDEgPT4gQXJyYXkgKCd2YWx1ZScgPT4gMjAwLCAncXVhbnRpdHknID0+IDMpLAogICAgICAgICAgICAgICAgMiA9PiBBcnJheSAoJ3ZhbHVlJyA9PiA1MDAsICdxdWFudGl0eScgPT4gMSksCiAgICAgICAgICAgICAgICAzID0+IEFycmF5ICgndmFsdWUnID0+IDIwMDAsICdxdWFudGl0eScgPT4gNCksCiAgICAgICAgICAgICAgICA0ID0+IEFycmF5ICgndmFsdWUnID0+IDUwMDAsICdxdWFudGl0eScgPT4gMSkKKTsKIAovLyDQnNCw0YHRgdC40LIg0LIg0LrQvtGC0L7RgNC+0Lwg0LzRiyDRhdGA0LDQvdC40Lwg0YDQtdC30YPQu9GM0YLQsNGCINCy0YvRh9C40YHQu9C10L3QuNC5ICRyZXN1bHRzWyRudW1CaWxsXVskY3VycmVudEFtb3VudF0KJHJlc3VsdHMgPSBhcnJheSgpOyAKCi8vINCn0LDRgdGC0LjRh9C90L7QtSDQt9Cw0L/QvtC70L3QtdC90LjQtSDQvNCw0YHRgdC40LLQsAovLyDQlNC70Y8g0LLRgdC10YUg0YHRg9C80Lwg0LHQsNC90LrQvdC+0YLQvtC5IDAg0YDQsNC30LzQtdC9INC90LUg0LLQstC+0LfQvNC+0LbQtdC9IChJTkYpCmZvciAoJGN1cnJlbnRBbW91bnQgPSAwOyAkY3VycmVudEFtb3VudCA8PSAkYW1vdW50OyAkY3VycmVudEFtb3VudCsrKSB7ICAgIAogICAgJHJlc3VsdHNbMF1bJGN1cnJlbnRBbW91bnRdID0gSU5GO30KICAgIAovLyDQldGB0LvQuCDQv9GA0L7RgdGP0YIg0YDQsNC30LzQtdC90Y/RgtGMINGB0YPQvNC80YMgMCwg0LPQvtGA0LTQviDQv9GA0L7RgtGP0LPQuNCy0LDQtdC8INC/0YPRgdGC0YPRjiDQu9Cw0LTQvtC90YwgKDAg0LHQsNC90LrQvdC+0YIpLgpmb3IgKCRudW1CaWxsID0gMDsgJG51bUJpbGwgPD0gY291bnQoJGJpbGxzKTsgJG51bUJpbGwrKykgeyAgICAKICAgICRyZXN1bHRzWyRudW1CaWxsXVswXSA9IDA7Cn0KCi8vICRjdXJyZW50QW1vdW50IC0g0YLQtdC60YPRidCw0Y8g0YHRg9C80LzQsCwg0LrQvtGC0L7RgNGD0Y4g0L3Rg9C20L3QviDQstGL0LTQsNGC0YwsINGD0LLQtdC70LjRh9C40LLQsNC10Lwg0L7RgiAxINC00L4g0YLRgNC10LHRg9C10LzQvtC5ICRhbW91bnQKZm9yKCRjdXJyZW50QW1vdW50ID0gMTsgJGN1cnJlbnRBbW91bnQgPD0gJGFtb3VudDsgJGN1cnJlbnRBbW91bnQrKykgewogICAgCiAgICAvLyDQn9C10YDQtdCx0LjRgNCw0LXQvCDQstGB0LUg0L3QvtC80LjQvdCw0LvRiyDQsdCw0L3QutC90L7RggogICAgZm9yZWFjaCAoJGJpbGxzIGFzICRudW1CaWxsID0+ICRiaWxsKSB7CiAgICAgICAgCiAgICAgICAgLy8g0J/QviDRg9C80L7Qu9GH0LDQvdC40Y4sINGC0LXQutGD0YnRg9GOINGB0YPQvNC80YMg0LzQvtC20L3QviDQstGL0LTQsNGC0Ywg0LHQsNC90LrQvdC+0YLQvtC5INC/0YDQtdC00YvQtNGD0YnQtdCz0L4g0L3QvtC80LjQvdCw0LvQsC4gICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICRyZXN1bHRzWyRudW1CaWxsXVskY3VycmVudEFtb3VudF0gPSAgJHJlc3VsdHNbJG51bUJpbGwtMV1bJGN1cnJlbnRBbW91bnRdOwogICAgICAgIAogICAgICAgIC8vINCV0YHRgtGMINC70Lgg0LHQsNC90LrQvdC+0YLRiyDRgtC10LrRg9GJ0LXQs9C+INC90L7QvNC40L3QsNC70LAg0Lgg0YLQtdC60YPRidGD0Y4g0YHRg9C80LzRgyDQvNC+0LbQvdC+INGA0LDQt9C80LXQvdGP0YLRjCDRgtC10LrRg9GJ0LjQvCDQvdC+0LzQuNC90LDQu9C+0LwgICAgICAgICAgIAogICAgICAgIGlmICgkYmlsbFsncXVhbnRpdHknXT4wICYmICRjdXJyZW50QW1vdW50ID49ICRiaWxsWyd2YWx1ZSddKSB7CiAgICAgICAgICAgIAogICAgICAgICAgICAvKiAg0J/QtdGA0LXQsdC40YDQsNC10Lwg0LrQvtC70LjRh9C10YHRgtCy0L4g0LHQsNC90LrQvdC+0YIg0YLQtdC60YPRidC10LPQviDQvdC+0LzQuNC90LDQu9CwCiAgICAgICAgICAgICAgICDQvtGCINC80LjQvdC40LzQsNC70YzQvdC+INGC0YDQtdCx0YPQtdC80L7Qs9C+ICjQuNC70Lgg0YLQvtCz0L4g0YfRgtC+INC10YHRgtGMKSDQtNC+IDEgKi8KICAgICAgICAgICAgZm9yICgkbWluUXVhbnQ9bWluKCRiaWxsWydxdWFudGl0eSddLCBpbnR2YWwoZmxvb3IoJGN1cnJlbnRBbW91bnQvJGJpbGxbJ3ZhbHVlJ10pKSk7ICRtaW5RdWFudCA+PSAxOyAkbWluUXVhbnQtLSkgewogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvKiAg0JLRi9Cx0LjRgNCw0LXQvCDQvNC40L3QuNC80LDQu9GM0L3QvtC1INC60L7Qu9C40YfQtdGB0YLQstC+INCx0LDQvdC60L3QvtGCINC00LvRjyDRgNCw0LfQvNC10L3QsCDQvNC10LbQtNGDINC00LDQvdC90L7QuSDQsdCw0L3QutC90L7RgtC+0Lkg0Lgg0L/RgNC10LTRi9C00YPRidC10LkKICAgICAgICAgICAgICAgICAgICDQtdGB0LvQuCDRgdGD0LzQvNGDINC80LXQvdGP0LXQvCDRgtC10LrRg9GJ0LXQuSDQsdCw0L3QutC90L7RgtC+0LksINGC0L4g0LfQsNC/0LjRgdGL0LLQsNC10Lwg0LrQvtC70LjRh9C10YHRgtCy0L4g0LHQsNC90LrQvdC+0YIKICAgICAgICAgICAgICAgICAgICDQtNC70Y8g0LTQsNC90L3QvtCz0L4g0L3QvtC80LjQvdCw0LvQsCDQuCDQutC+0LvQuNGH0LXRgdGC0LLQviDQvNC+0L3QtdGCINC/0YDQtdC00YvQtNGD0YnQuNGFINC90L7QvNC40L3QsNC70L7Qsiwg0LTQu9GPINGA0LDQt9C80LXQvdCwINC+0YHRgtCw0YLQutCwINGB0YPQvNC80YsgICovCiAgICAgICAgICAgICAgICAkcmVzdWx0c1skbnVtQmlsbF1bJGN1cnJlbnRBbW91bnRdID0gIG1pbigkcmVzdWx0c1skbnVtQmlsbF1bJGN1cnJlbnRBbW91bnRdLCAkcmVzdWx0c1skbnVtQmlsbC0xXVskY3VycmVudEFtb3VudCAtICRtaW5RdWFudCAqICRiaWxsWyd2YWx1ZSddXSArICRtaW5RdWFudCk7IAogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9ICAgCgoKLy8g0KQt0Y8g0YHRh9C40YLQsNC10YIg0LHQsNC90LrQvdC+0YLRiyDQtNC70Y8g0YDQsNC30LzQtdC90Ysg0YLRgNC10LHRg9C10LzQvtC5INGB0YPQvNC80Ysg0LTQu9GPINCQ0L3QvtC90LAgCi8vINCw0YDQs9GD0LzQtdC90YLRizog0LzQsNGB0YHQuNCyINGBINGA0LXQt9GD0LvRjNGC0LDRgtC+0LwsINCx0LDQvdC60L3QvtGC0YsgKNC90L7QvNC40L3QsNC7L9C60L7Quy3QstC+KSwg0LrQvtC7LdCy0L4g0L3QvtC80LjQvdCw0LvQvtCyLCDRgdGD0LzQvNCwINC00LvRjyDQstGL0LTQsNGH0LgsINC+0YLQstC10YIKZnVuY3Rpb24gZmluZEFucygkcmVzdWx0cywgJGJpbGxzLCAkbnVtQmlsbCwgJGFtb3VudCwgJGFucykgewogICAgCiAgICB3aGlsZSAoJHJlc3VsdHNbJG51bUJpbGxdWyRhbW91bnRdICE9IDApIHsgCiAgICAgICAgCiAgICAgICAgLyogINC10YHQu9C4INC00LvRjyDRgNCw0LfQvNC10L3QsCDRgtC10LrRg9GJ0LXQuSDRgdGD0LzQvNGLINC60L7Qu9C40YfQtdGB0YLQstC+INCx0LDQvdC60L3QvtGCINC/0YDQvtGI0LvQvtCz0L4g0L3QvtC80LjQvdCw0LvQsCDQvdGD0LbQvdC+INGB0YLQvtC70YzQutC+INC20LUsCiAgICAgICAgICAgINGC0L4g0L/QtdGA0LXRhdC+0LTQuNC8INC6INC/0YDQtdC00YvQtNGD0YnQtdC80YMg0L3QvtC80LjQvdCw0LvRgyAqLwogICAgICAgIGlmICgkcmVzdWx0c1skbnVtQmlsbC0xXVskYW1vdW50XSA9PSAkcmVzdWx0c1skbnVtQmlsbF1bJGFtb3VudF0pIHsgCiAgICAgICAgICAgICRudW1CaWxsLS07CiAgICAKICAgICAgICAvKiAg0LXRgdC70Lgg0YLQtdC60YPRidGD0Y4g0YHRg9C80LzRgyDQvNC+0LbQvdC+INC90LXRgdC60L7Qu9GM0LrQviDRgNCw0Lcg0LLRi9C00LDRgtGMINGC0LXQutGD0YnQtdC5INCx0LDQvdC60L3QvtGC0L7QuSwg0LTQtdC70LDQtdC8INGN0YLQviwKICAgICAgICAgICAg0Lgg0LTQvtCx0LDQstC70Y/QtdC8INGC0LXQutGD0YnRg9GOINCx0LDQvdC60L3QvtGC0YMg0Log0YDQtdC30YPQu9GM0YLQsNGC0YMg0Lgg0YPQvNC10L3RjNGI0LDQtdC8INGB0YPQvNC80YMg0LLRi9C00LDRh9C4INC90LAg0YLQtdC60YPRidC40Lkg0L3QvtC80LjQvdCw0LsqLwogICAgICAgIH0gZWxzZWlmICgkcmVzdWx0c1skbnVtQmlsbF1bJGFtb3VudF0gPj0gJHJlc3VsdHNbJG51bUJpbGxdWyRhbW91bnQtJGJpbGxzWyRudW1CaWxsXVsndmFsdWUnXV0pIHsKICAgICAgICAgICAgaWYgKGlzc2V0KCRhbnNbJGJpbGxzWyRudW1CaWxsXVsndmFsdWUnXV0pKSB7CiAgICAgICAgICAgICAgICAkYW5zWyRiaWxsc1skbnVtQmlsbF1bJ3ZhbHVlJ11dKys7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgJGFuc1skYmlsbHNbJG51bUJpbGxdWyd2YWx1ZSddXT0xOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRhbW91bnQgLT0gJGJpbGxzWyRudW1CaWxsXVsndmFsdWUnXTsKICAgICAgICAgCiAgICAgICAgLyogINC10YHQu9C4INC+0YHRgtCw0YLQvtC6INGC0LXQutGD0YnQtdC5INGB0YPQvNC80YssINC/0L7RgdC70LUg0YDQsNC30LzQtdC90LAg0YLQtdC60YPRidC10Lkg0LHQsNC90LrQvdC+0YLQvtC5LCDQvNC+0LbQvdC+INCy0YvQtNCw0YLRjCDRgtC+0LvRjNC60L4KICAgICAgICAgICAg0LHQsNC90LrQvdC+0YLQvtC5INC/0YDQtdC00YvQtNGD0YnQtdCz0L4g0L3QvtC80LjQvdCw0LvQsCwg0YLQsNC6INGC0L7QvNGDINC4INCx0YvRgtGMLCArIDEg0Log0YDQtdC30YPQu9GM0YLQsNGC0YMsINC/0LXRgNC10YXQvtC00LjQvCDQugogICAgICAgICAgICDQv9GA0LXQtNGL0LTRg9GJ0LXQvNGDINC90L7QvNC40L3QsNC70YMg0Lgg0YPQvNC10L3RjNGI0LDQtdC8INGB0YPQvNC80YMg0LLRi9C00LDRh9C4INC90LAg0YLQtdC60YPRidC40Lkg0L3QvtC80LjQvdCw0LsgKi8gICAKICAgICAgICB9IGVsc2UgeyAgCiAgICAgICAgICAgIGlmIChpc3NldCgkYW5zWyRiaWxsc1skbnVtQmlsbF1bJ3ZhbHVlJ11dKSkgewogICAgICAgICAgICAgICAgJGFuc1skYmlsbHNbJG51bUJpbGxdWyd2YWx1ZSddXSsrOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICRhbnNbJGJpbGxzWyRudW1CaWxsXVsndmFsdWUnXV09MTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkbnVtQmlsbC0tOwogICAgICAgICAgICAkYW1vdW50IC09ICRiaWxsc1skbnVtQmlsbF1bJ3ZhbHVlJ107ICAgIAogICAgICAgIH0KICAgIH0KICAgIHByaW50QW5zICgkYW5zKTsgLy8g0L7RgtC/0YDQsNCy0LvRj9C10Lwg0L7RgtCy0LXRgiDQvdCwINC/0LXRh9Cw0YLRjAp9Ci8vINCf0YDQvtCy0LXRgNGP0LXQvCDRgdGD0YnQtdGB0YLQstGD0LXRgiDQu9C4INC+0YLQstC10YIg0LTQu9GPINC00LDQvdC90L7QuSDRgdGD0LzQvNGLLCDQt9C+0LLQtdC8IGZpbmRBbnMg0LjQu9C4INGA0YPQs9Cw0LXQvNGB0Y8uCmZ1bmN0aW9uIGNoZWNrQW5zKCRyZXN1bHRzLCAkYmlsbHMsICRudW1CaWxsLCAkYW1vdW50LCAkYW5zKSB7CiAgICBpZiAoJHJlc3VsdHNbJG51bUJpbGxdWyRhbW91bnRdPT1JTkYpIHsKICAgICAgICAkYW5zWydyZXN1bHQnXT1OVUxMOwogICAgICAgIHByaW50QW5zICgkYW5zKTsgLy8g0L7RgtC/0YDQsNCy0LvRj9C10Lwg0L7RgtCy0LXRgiDQvdCwINC/0LXRh9Cw0YLRjAogICAgfSBlbHNlIHsKICAgICAgICAkYW5zID0gZmluZEFucygkcmVzdWx0cywgJGJpbGxzLCAkbnVtQmlsbCwgJGFtb3VudCwgJGFucyk7CiAgICB9Cn0KCi8vINCS0YvQstC+0LTQuNC8INGA0LXQt9GD0LvRjNGC0LDRggpmdW5jdGlvbiBwcmludEFucyAoJGFucykgewogICAgCiAgICBlY2hvICLQodGD0LzQvNCwOiB7JGFuc1snYW1vdW50J119XG4iOwogICAgCiAgICBpZiAoJGFuc1sncmVzdWx0J109TlVMTCkgewogICAgICAgIGVjaG8gItCi0YDQtdCx0YPQtdC80YPRjiDRgdGD0LzQvNGDINCy0YvQtNCw0YLRjCDQvdC10LLQvtC30LzQvtC20L3QviI7CiAgICB9IGVsc2UgewogICAgICAgIGVjaG8gItCS0YvQtNCw0YfQsCDQstC+0LfQvNC+0LbQvdCwLCDRh9C40YHQu9C+INC60YPQv9GO0YA6XG4iOwogICAgICAgIAogICAgICAgIGZvcmVhY2goJGFucyBhcyAkYmlsbFZhbHVlID0+ICRxdWFudGl0eSkgewogICAgICAgICAgICBpZiAoJGJpbGxWYWx1ZSE9MCkgewogICAgICAgICAgICAgICAgZWNobyAieyRxdWFudGl0eX14eyRiaWxsVmFsdWV9IiAuICIgIjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQoKLy8g0JfQsNC/0YPRgdC60LDQtdC8INC/0YDQvtCy0LXRgNC60YMKY2hlY2tBbnMoJHJlc3VsdHMsICRiaWxscywgY291bnQoJGJpbGxzKSwgJGFtb3VudCwgJGFucyk7Cj8+