C#でトップダウンアプローチを使ってコイン両替問題を実装する方法
コイン両替問題とは
コイン両替問題は、指定された金額を最小枚数のコインで作るという古典的な動的計画法(DP)の問題です。本記事では、C#を用いて「トップダウンアプローチ(メモ化再帰)」でこの問題を解く方法を解説します。
アルゴリズムの基本構造
CoinChangeTopDownApproach メソッドは、次の4つのパラメータを受け取ります。
- n:作りたい金額
- coins:使用できるコインの種類を格納した配列
- t:コインの総数
- dp:計算済みの値をキャッシュするための配列
処理の流れは以下の通りです。
- 金額が0なら0を返します(これ以上コインは不要なため)。
- dp配列に既に計算済みの値があれば、それをそのまま返し、無駄な再計算を防ぎます。
- まだ計算されていない場合は、各コインを使った部分問題を再帰的に呼び出し、得られた結果の最小値に1を加えて答えとし、dp配列に保存してから返します。
計算量
- 時間計算量:O(N)
- 空間計算量:O(N)
実装例
public class DynamicProgramming{ public int CoinChangeTopDownApproach(int n,int[] coins,int t,int[] dp){ if (n == 0){ return 0; } if (dp[n] != 0){ return dp[n]; } int ans = int.MaxValue; for (int i = 0; i < t; i++){ if (n - coins[i] >= 0){ int subprob = CoinChangeTopDownApproach(n - coins[i], coins, t, dp); ans = Math.Min(ans, subprob + 1); } } dp[n] = ans; return dp[n]; }}static void Main(string[] args){ DynamicProgramming dp = new DynamicProgramming(); int N = 15; int[] coins = { 1, 7, 10 }; int[] dp1 = new int[100]; int t = coins.Count(); int res = dp.CoinChangeTopDownApproach(15, coins, t, dp1); Console.WriteLine(res);}出力結果
3
実行結果の解説
この例では、金額15をコイン {1, 7, 10} で作ることを考えます。「7 + 7 + 1」のように7円玉を2枚と1円玉を1枚使えば、合計3枚で金額15を作れます。他の組み合わせ(例:10 + 1×5)よりも少ない枚数であるため、プログラムは最小枚数である「3」を出力します。
トップダウンアプローチでは、一度計算した金額に対する答えをdp配列に記録するため、同じ部分問題を何度も計算することがなくなり、素朴な再帰に比べて大幅に効率が向上します。
-
C++のnew演算子を使って2次元配列を動的に宣言・生成する方法
動的な2次元配列とは、基本的に「配列へのポインタ」を要素とする配列(ポインタの配列)のことです。つまり、各行が独立した1次元配列としてヒープ上に確保され、それらの先頭アドレスを格納するポインタ配列によって全体が管理されます。下図は、3×4の2次元配列のイメージです。アルゴリズムC++のnew演算子で2次元配列を動的に確保する手順は以下の通りです。Begin 配列の寸法(行数・列数)を宣言する。 new を使って 2次元配列 a[][] を動的に確保する。 配列に要素を代入する。 配列の内容を出力する。 delete でメモリを解放する。 Endサンプルコ
-
Java 9でJavaFXを使ってJShellをプログラムから実装する方法
JShellは、サンプル式を対話的に実行できるツールです。通常はコマンドラインから利用しますが、JavaFXアプリケーションの中でプログラム的にJShellを実装することも可能です。その場合、Javaプログラムに以下のパッケージをインポートする必要があります。import jdk.jshell.JShell; import jdk.jshell.SnippetEvent; import jdk.jshell.VarSnippet;これらのクラスの役割は次のとおりです。JShell:評価エンジンの本体。式や文を評価(eval)するためのAPIを提供します。SnippetEvent:評価結果として