Имейте в виду, что этот код просто отвечает на ваш вопрос о том, кто ограничивает ваш номер монеты, но ваш алгоритм не является полным, так как вы не считаете большим количеством угловых случаев.
static void Main(string[] args)
{
var amount = 100000;
var availabeCoins = new CoinPack[]
{
new CoinPack { Value = 500, Amount = 2 },
new CoinPack { Value = 100, Amount = 3 },
new CoinPack { Value = 50, Amount = 5 },
new CoinPack { Value = 20, Amount = 1 },
new CoinPack { Value = 10, Amount = 2 },
new CoinPack { Value = 5, Amount = 0 },
new CoinPack { Value = 2, Amount = 10 },
new CoinPack { Value = 1, Amount = 500 }
};
var usedCoins = new CoinPack[]
{
new CoinPack { Value = 500 },
new CoinPack { Value = 100 },
new CoinPack { Value = 50 },
new CoinPack { Value = 20 },
new CoinPack { Value = 10 },
new CoinPack { Value = 5 },
new CoinPack { Value = 2 },
new CoinPack { Value = 1 }
};
for (int i = 0; i < availabeCoins.Length; i++)
{
usedCoins[i].Amount = amount/availabeCoins[i].Value;
if (usedCoins[i].Amount > availabeCoins[i].Amount)
{
usedCoins[i].Amount = availabeCoins[i].Amount;
}
amount -= usedCoins[i].Amount * usedCoins[i].Value;
}
foreach (var usedCoin in usedCoins)
{
Console.WriteLine(usedCoin.Value + " " + usedCoin.Amount);
}
}
class CoinPack
{
public int Value;
public int Amount;
}
UPD Это решение является довольно неэффективным, но я предполагаю, что это решит вашу проблему. Вы можете взять его как ссылку и улучшить ее самостоятельно.
void Main(string[] args)
{
var amount = 6;
var availabeCoins = new List<CoinPack>
{
new CoinPack { Value = 500, Amount = 0 },
new CoinPack { Value = 100, Amount = 0 },
new CoinPack { Value = 50, Amount = 0 },
new CoinPack { Value = 20, Amount = 0 },
new CoinPack { Value = 10, Amount = 0 },
new CoinPack { Value = 5, Amount = 1 },
new CoinPack { Value = 2, Amount = 3 },
new CoinPack { Value = 1, Amount = 0 }
};
var usedCoins = new List<CoinPack>
{
new CoinPack { Value = 500, Amount = 0 },
new CoinPack { Value = 100, Amount = 0 },
new CoinPack { Value = 50, Amount = 0 },
new CoinPack { Value = 20, Amount = 0 },
new CoinPack { Value = 10, Amount = 0 },
new CoinPack { Value = 5, Amount = 0 },
new CoinPack { Value = 2, Amount = 0 },
new CoinPack { Value = 1, Amount = 0 }
};
if (Change(amount, availabeCoins, usedCoins) != null)
{
foreach (var usedCoin in usedCoins)
{
Console.WriteLine(usedCoin.Value + " " + usedCoin.Amount);
}
}
else
{
Console.WriteLine("Cannot find exact change");
}
}
List<CoinPack> Change(int amount, List<CoinPack> availableCoins, List<CoinPack> usedCoins)
{
if (amount == 0)
{
return availableCoins;
}
if (amount < 0)
{
return null;
}
foreach (var availableCoin in availableCoins.Where(ac => ac.Amount > 0 && amount >= ac.Value))
{
var newAvailableCoins = CopyCoins(availableCoins);
newAvailableCoins.First(c => c.Value == availableCoin.Value).Amount--;
var change = Change(amount - availableCoin.Value, newAvailableCoins, usedCoins);
if (change == newAvailableCoins)
{
usedCoins.First(c => c.Value == availableCoin.Value).Amount++;
return availableCoins;
}
}
return null;
}
List<CoinPack> CopyCoins(List<CoinPack> coinPacks)
{
var copy = new List<CoinPack>();
foreach (var coinPack in coinPacks)
{
copy.Add(new CoinPack { Value = coinPack.Value, Amount = coinPack.Amount });
}
return copy;
}
class CoinPack
{
public int Value;
public int Amount;
}
Сделать целочисленный массив максимумов и делать мин (Результаты, maxAmount [я]) * монеты [я]. –
Кроме того, переименуйте 'Results' в нечто более значимое, например' currentCoinCount', все может быть немного яснее. Вы можете также рассмотреть возможность использования 'amount% = coins [i];' вместо 'amount - = Results * coins [i]', чтобы было ясно, что вы берете остаток. –
Это тесно связано с определенными проблемами NP-рюкзака. – CodesInChaos