using System.Collections.Generic;
namespace MoneyPermutation
private static IList<int> s_availableAmounts = new int[] {
500, 1000, 2000, 5000, 10000, 20000, 50000
static long NumberOfWaysToPay(long bill)
var gcd = s_availableAmounts.First();
var bank = s_availableAmounts.Select(amount => amount / gcd).ToArray();
var dp = new long[bank.Length, bill+1];
for (var i = 0; i < bank.Length; ++i)
for (long j = 0; j <= bill; ++j)
for (var k = 0; k <= i; ++k)
dp[i, j] += dp[k, prev_j];
for (var i = 0; i < bank.Length-1; ++i) result += dp[i, bill];
public static int Main(string[] args)
args = new String[] {"2000"};
var billArgument = args.FirstOrDefault();
if (billArgument == null)
Console.WriteLine("No argument provided.");
if (!long.TryParse(billArgument, out bill) || bill % s_availableAmounts.First() != 0)
Console.WriteLine(string.Format(
"Argument is not a valid integer that is divisible by {0}.",
s_availableAmounts.First()));
var result = NumberOfWaysToPay(bill);
"Number of ways to pay bill of {0} VND using one of ({1}) VND banknotes:\n{2}",
string.Join(", ", s_availableAmounts),