まず、部分和問題のアルゴリズムには2つのアプローチがあります。1つは再帰的なトップダウンの方法であり、もう1つは反復的なボトムアップの方法です。ここでは、反復的なボトムアップの方法を紹介します。
- ボトムアップのアルゴリズムの実装:
- 部分和問題を解くために必要な配列を作成します。この配列は、[要素の数 + 1][目標の合計値 + 1]のサイズを持ちます。
- 配列の要素をすべて初期化し、部分和問題の基本的な状態を設定します。つまり、配列の最初の行と最初の列を0で埋めます。
- 配列の2行目から順に、与えられた整数の集合の要素を1つずつ取り出します。
- 配列の各要素に対して、以下の条件分岐を行います。
- もし現在の要素を選んで目標の合計値を達成できる場合、配列の対応する位置を1に更新します。
- もし現在の要素を選ばずに目標の合計値を達成できる場合、配列の対応する位置を0または1に更新します(状況によって異なります)。
- 配列の最後の要素が1であれば、目標の合計値を達成する組み合わせが存在します。そうでなければ、存在しません。
以下に、Javaで部分和問題のアルゴリズムを実装する例を示します。
public class SubsetSum {
public static boolean hasSubsetSum(int[] set, int target) {
int n = set.length;
boolean[][] dp = new boolean[n + 1][target + 1];
// ベースケースの初期化
for (int i = 0; i <= n; i++) {
dp[i][0] = true;
}
// ボトムアップの計算
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= target; j++) {
if (set[i - 1] <= j) {
dp[i][j] = dp[i - 1][j - set[i - 1]] || dp[i - 1][j];
} else {
dp[i][j] = dp[i - 1][j];
}
}
}
return dp[n][target];
}
public static void main(String[] args) {
int[] set = {3, 34, 4, 12, 5, 2};
int target = 9;
if (hasSubsetSum(set, target)) {
System.out.println("目標の合計値を達成する組み合わせが存在します。");
} else {
System.out.println("目標の合計値を達成できる組み合わせは存在しません。");
}
}
}