LeetCode 322タイトル:変更コンバーチブル(動的計画法)

住所:HTTPS://leetcode-cn.com/problems/coin-change/

二つのことに注意してください。

図1に示すように、dp上限値、それらは全て整数であるので、したがってamount + 1
2、場所から転送することができる出発算出することができる
3、及び完全ナップザック問題が発生されたコンタクト。

方法の一つ:動的計画

「ダイナミックプログラミング」のアイデアの最も基本的な使用。

ステップ1:ステータスの定義

dp[i]メイクアップの量を表すiコインの最小数を。

ステップ2:状態遷移方程式

coins = [1, 2, 5]1 タイトル: amount = 11、。想像するのは簡単です:

総量は11、選択されたコインのリストに従ってことができ[1, 2, 5]、このように分解されます。

  • 11 = 1 + (11 - 1):それが表す11の金種に分割される1コインの額面構成する10硬貨の数と最小値と、
  • 11 = 2 + (11 - 2):それが表す11の金種に分割される2コインの額面構成する9硬貨の数と最小値と、
  • 11 = 5 + (11 - 5):それが表す11の金種に分割される5コインの額面構成する6硬貨の数と最小値と、

三つは、最小値をとります。下の書き込み状態遷移方程式:

D P [ i ] = min { 1 + d p [ i c o i n s [ j ] ] } DP [I] = \分\ {1 + DP [I - コイン[J] \}

ここではjコインの数のリストです。i - coins[j]以上である必要があり0、それは理にかなっています。

また、注意してください:2人の非常に特別な地位があります。

図1に示すようにdp[0]0シートが基準値となる場合、この金種は、5の合計公称値場合、単に金種の硬貨5を有していることもあり、この時点でdp[5] = 1 + dp[5 - 5] = 1、それが提供されますdp[0] = 1

2は、実施例2の場合が表示されることがあり、この時間は、設定する必要がありdp[i] = - 1、この質問は、したがって、初期化時間を設定することはできません、最小を頼まれ0、それは十分な大きさの数に設定する必要があります。

ステップ3:初期化

(私たちが議論されてきた上)

ステップ4:出力

出力がdp[amount]可能。

ステップ5:缶圧縮の状態

各ステップは、前の状態に使用することができるので、圧縮することができません。

もう一度自分自身を思い出させる:時間の初期化を、比較したいのでは最小であるため、初期化することはできません 1 -1 そして、ここに 1 -1 特別な意味を持っています。

Javaコード:

import java.util.Arrays;

public class Solution {

    public int coinChange(int[] coins, int amount) {
        // 给 0 占位
        int[] dp = new int[amount + 1];

        // 注意:因为要比较的是最小值,这个不可能的值就得赋值成为一个最大值
        Arrays.fill(dp, amount + 1);

        dp[0] = 0;

        for (int i = 1; i <= amount; i++) {
            for (int coin : coins) {
                if (i - coin >= 0 && dp[i - coin] != -1) {
                    dp[i] = Math.min(dp[i], 1 + dp[i - coin]);
                }
            }

            if (dp[i] == amount + 1) {
                dp[i] = -1;
            }
        }

        if (dp[amount] == amount + 1) {
            dp[amount] = -1;
        }
        return dp[amount];
    }
}

あなたは、「フルバックパック」テンプレートを使用することができます。(私は特にはっきりしていたとは思いませんでしたので、コードは、正しいです。)

import java.util.Arrays;

public class Solution {

    public int coinChange(int[] coins, int amount) {
        int[] dp = new int[amount + 1];
        Arrays.fill(dp, amount + 1);
        dp[0] = 0;

        for (int coin : coins) {
            for (int i = coin; i <= amount; i++) {
                dp[i] = Math.min(dp[i], dp[i - coin] + 1);
            }
        }

        if (dp[amount] == 9999) {
            dp[amount] = -1;
        }
        return dp[amount];
    }
}

注:1、初期化時間、それに割り当てられた多数は、整数の最大値は、クロスボーダーを引き起こす可能性があります。

図2は、コード内の印刷出力を行う時間が遅くなることはありません。

公開された442元の記事 ウォンの賞賛330 ビュー123万+

おすすめ

転載: blog.csdn.net/lw_power/article/details/103872888