コードカプリス合宿44日目 | 518.チェンジエクスチェンジⅡ 377.コンビネーションサムⅣ

@TOC _


序文

コードランダムレコードアルゴリズムトレーニングキャンプ 44日目


1. リートコード 518. チェンジエクスチェンジ II

1. トピック

さまざまな金種のコインを表す整数配列のコインと、合計金額を表す整数の金額が与えられます。

合計金額を構成できるコインの組み合わせの数を計算して返してください。合計金額に達しないコインの組み合わせがある場合は、0 を返します。

各金種のコインが無限にあると仮定します。

タイトル データは、結果が 32 ビットの符号付き整数に収まることを保証します。

例 1:

入力: 金額 = 5、コイン = [1, 2, 5] 出力: 4 説明: 合計金額を計算するには 4 つの方法があります: 5=5 5=2+2+1 5=2+1+1+1 5 =1+1+1+1+1

例 2:

入力: 金額 = 3、コイン = [2] 出力: 0 説明: 合計金額 3 は、金種 2 のコインだけでは構成できません。

例 3:

入力: 金額 = 10、コイン = [10] 出力: 1

ヒント:

1 <= coins.length <= 300
1 <= coins[i] <= 5000
coins 中的所有值 互不相同
0 <= amount <= 5000

出典: LeetCode リンク: https://leetcode.cn/problems/coin-change-ii

2. 問題解決のアイデア

方法 1: 動的プログラミング

この質問では、合計金額 amountamount と配列 Coinscoins が与えられた場合、合計が amountamount に等しいコインの組み合わせの数を計算する必要があります。このうち、coinscoins の各要素は、選択された要素の順序に関係なく複数回選択できるため、この問題では選択されたコインの組み合わせの数を計算する必要があります。

可能な組み合わせの数は、動的計画法によって計算できます。dp[x]dp[x] を使用して、合計が xx に等しいコインの組み合わせの数を表します。目的は、dp[amount]dp[amount] を見つけることです。

動的プログラミングの範囲は dp[0]=1dp[0]=1 です。コインが選択されなかった場合にのみ金額の合計が 00 になるため、コインの組み合わせは 11 通りしかありません。

Coincoin の額面のコインの場合、coin≤i≤amountcoin≤i≤amount の場合、合計が i-coini-coin に等しいコインの組み合わせがある場合、そのコインの組み合わせに Coincoin の額面のコインを追加します。合計がiiとなるコインの組み合わせが得られます。したがって、coinscoins をトラバースし、その中の硬貨の金種ごとに、配列 dpdp の金種以上の各要素の値を更新する必要があります。

これは動的プログラミングにつながります。

初始化 dp[0]=1dp[0]=1;

遍历 coinscoins,对于其中的每个元素 coincoin,进行如下操作:
    遍历 ii 从 coincoin 到 amountamount,将 dp[i−coin]dp[i−coin] 的值加到 dp[i]dp[i]。

最终得到 dp[amount]dp[amount] 的值即为答案。

上記のアプローチでは、異なる順列を二重にカウントしません。外側のループは配列 Coincoins の値をトラバースしているため、内側のループはさまざまな金額の合計をトラバースしています。dp[i]dp[i] の値を計算するとき、金額の合計が等しいことを確認できます。 ii の硬貨の額面の順序に、順序が決定されているため、異なる順列が二重にカウントされることはありません。

たとえば、coins=[1,2]coins=[1,2] の場合、dp[3]dp[3] を計算するには、まずコイン額面 11 をトラバースし、次にコイン額面 22 をトラバースする必要があります。ただし、次の場合のみです。 22 通りの組み合わせが表示されます。

3=1+1+13=1+233 =1+1+1=1+2

コイン金種22がコイン金種11の前に現れることは不可能である、すなわち、3=2+13=2+1の二重カウントは存在しない。

3. コードの実装

```java class Solution { public int change(int amount, int[] Coins) { int[] dp = new int[amount + 1]; dp[0] = 1; for (int コイン : コイン) { for (int i = コイン; i <= 金額; i++) { dp[i] += dp[i - コイン]; dp[量]を返します。} }

「」

2. Leetcode 377. 合計値Ⅳ

1. トピック

個別の整数の配列 nums と、ターゲット整数 target が与えられます。numsから求めて合計が対象となる要素の組み合わせの数を返します。

質問データは、回答が 32 ビット整数の範囲内に収まることを保証します。

例 1:

入力: nums = [1,2,3]、ターゲット = 4 出力: 7 説明: 可能なすべての組み合わせは次のとおりです: (1, 1, 1, 1) (1, 1, 2) (1, 2, 1) ( 1 , 3) (2, 1, 1) (2, 2) (3, 1) 順序が異なるシーケンスは異なる組み合わせとして扱われることに注意してください。

例 2:

入力: nums = [9]、ターゲット = 3 出力: 0

ヒント:

1 <= nums.length <= 200
1 <= nums[i] <= 1000
nums 中的所有元素 互不相同
1 <= target <= 1000

出典: LeetCode リンク: https://leetcode.cn/problems/combination-sum-iv

2. 問題解決のアイデア

方法 1: 動的プログラミング

この問題では、配列 numsnums とターゲット値 targettarget が与えられた場合、numsnums からいくつかの要素を選択し、それらの合計が targettarget に等しくなるように解の数を計算する必要があります。このうち、numsnums の各要素は複数回選択可能であり、要素を選択する順序を考慮する必要があります。選択された要素の順序を考慮する必要があるため、この質問で計算する必要があるのは、選択された要素の順列の数です。

可能な解の数は動的計画法によって計算できます。dp[x]dp[x] を使用して、選択した要素の合計が xx に等しい解の数を表します。目的は、dp[target]dp[target] を見つけることです。

動的プログラミングの範囲は dp[0]=1dp[0]=1 です。要素が選択されていない場合のみ要素の合計が 00 になるため、選択肢は 11 個のみです。

1≤i≤target1≤i≤target の場合、要素の合計が ii に等しい順列がある場合、順列の最後の要素は配列 numsnums 内の要素でなければなりません。配置の最後の要素が numnum であると仮定すると、num ≤ inum ≤ i でなければなりません。要素の合計が i-numi-num に等しい各配置について、最後に numnum を追加すると、要素の合計を取得できますii Permutations に等しいため、dp[i]dp[i] を計算するときは、すべての dp[i−num]dp[i−num] の合計を計算する必要があります。

これは動的プログラミングにつながります。

初始化 dp[0]=1dp[0]=1;

遍历 ii 从 11 到 targettarget,对于每个 ii,进行如下操作:
    遍历数组 numsnums 中的每个元素 numnum,当 num≤inum≤i 时,将 dp[i−num]dp[i−num] 的值加到 dp[i]dp[i]。

最终得到 dp[target]dp[target] 的值即为答案。

上記のアプローチでは、要素が選択される順序が考慮されていますか? 答えは「はい」です。外側のループは 11 から targettarget までの値を移動し、内側のループは配列 numsnums の値を移動するため、dp[i]dp[i] の値を計算するとき、numsnums の各要素は以下になります。から ii は、要素の合計が ii の順列の最後の要素に等しいとして使用できます。たとえば、11 と 33 の両方が配列 numsnums にあり、dp[4]dp[4] を計算する場合、配列の最後の要素は 11 または 33 になる可能性があるため、dp[1]dp[1] と dp[3] dp[3] が考慮されます。つまり、異なる次数が考慮されます。

3. コードの実装

```java クラス Solution { public int comboSum4(int[] nums, int target) { int[] dp = new int[target + 1]; dp[0] = 1; for (int i = 1; i <= target; i++) { for (int num : nums) { if (num <= i) { dp[i] += dp[i - num]; dp[ターゲット]を返します。} }

「」

おすすめ

転載: blog.csdn.net/HHX_01/article/details/131285407