/// <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); }