示例#1
0
        /// <summary>
        /// Метод, получающий монеты от клиента
        /// </summary>
        private static void getMoney()
        {
            Console.WriteLine("\nConsumer's wallet consists of:{0}Please choose coin (input it value)", client.Money);
            int value;

            if (int.TryParse(Console.ReadLine(), out value))
            {
                if (client.GiveCoin(value))
                {
                    moneyInside.addCoin(value);
                    clientDeposit += value;
                    Console.WriteLine("\nCoin \"{0}\" inserted successfully. Credit {1} roubles.", value, clientDeposit);
                }
                else
                {
                    //исключительная ситуация, когда у человека в кошельке нет монеты такого номинала
                    Console.WriteLine("\nNo such coin. Try again.");
                }
            }
            else
            {
                //нет такого номинала монет
                Console.WriteLine("\nNo such coin. Try again.");
            }
        }
示例#2
0
        /// <summary>
        /// Метод, набирающий сумму, равную или наиболее близкую из возможных к значению параметра из существующих монет.
        /// Сначала для экономии времени используется алгоритм жадной упаковки, затем, в случае неуспеха,
        /// алгоритм динамического программирования, обеспечивающий оптимальный результат.
        /// </summary>
        /// <param name="clientDeposit">Набираемая сумма.</param>
        /// <returns>Список взятых монет.</returns>
        public Money getCoins(int clientDeposit)
        {
            Money result  = new Money();
            int   deposit = clientDeposit;//copy for later dp usage

            //try greedy algorithm
            while (clientDeposit >= (int)Coin.TEN && getCoin((int)Coin.TEN))
            {
                clientDeposit -= (int)Coin.TEN;
                result.addCoin((int)Coin.TEN);
            }
            while (clientDeposit >= (int)Coin.FIVE && getCoin((int)Coin.FIVE))
            {
                clientDeposit -= (int)Coin.FIVE;
                result.addCoin((int)Coin.FIVE);
            }
            while (clientDeposit >= (int)Coin.TWO && getCoin((int)Coin.TWO))
            {
                clientDeposit -= (int)Coin.TWO;
                result.addCoin((int)Coin.TWO);
            }
            while (clientDeposit >= (int)Coin.ONE && getCoin((int)Coin.ONE))
            {
                clientDeposit -= (int)Coin.ONE;
                result.addCoin((int)Coin.ONE);
            }

            if (clientDeposit > 0)
            {
                //if we can't to return all change with greedy algorithm
                //return all taken coins back
                addCoins(result);
                //and try dynamic programming for more right solution of classical Knapsack problem
                result = getCoinsDP(deposit);
                //now take all coins in result from this money
                removeCoins(result);
            }
            return(result);
        }
示例#3
0
        /// <summary>
        /// Метод, набирающий монеты стоимостью, наиболее близкой к deposit методом динамического программирования.
        /// Используется в методе public Money getCoins(int clientDeposit).
        /// </summary>
        /// <param name="deposit">Набираемая сумма.</param>
        /// <returns>Список взятых монет.</returns>
        private Money getCoinsDP(int deposit)
        {
            List <int> cs = CoinsDictToList(this.coins);
            int        n  = cs.Count;

            int[,] M = new int[n, deposit + 1];
            int i, j;

            //table filling
            for (i = 0; i < n; i++)
            {
                for (j = 0; j <= deposit; j++)
                {
                    int coin = cs[i];
                    if (coin > j)
                    {
                        M[i, j] = (i == 0) ? 0 : M[i - 1, j];
                    }
                    else
                    {
                        if (i == 0)
                        {
                            M[i, j] = coin;
                        }
                        else
                        {
                            int pr  = M[i - 1, j];
                            int now = M[i - 1, j - coin] + coin;
                            M[i, j] = (pr > now) ? pr : now;
                        }
                    }
                }
            }
            //result getting
            Money result = new Money();

            i = n - 1;
            j = deposit;
            while (M[i, j] > 0 && i >= 0)
            {
                if (i == 0)
                {
                    result.addCoin(cs[i]);
                    j -= cs[i];
                }
                else
                {
                    if (M[i, j] == M[i - 1, j])
                    {
                        i--;
                    }
                    else
                    {
                        result.addCoin(cs[i]);
                        j -= cs[i];
                        i--;
                    }
                }
            }
            return(result);
        }