住所: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
硬貨の数と最小値と、
三つは、最小値をとります。下の書き込み状態遷移方程式:
ここでは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:缶圧縮の状態
各ステップは、前の状態に使用することができるので、圧縮することができません。
もう一度自分自身を思い出させる:時間の初期化を、比較したいのでは最小であるため、初期化することはできません 。そして、ここに 特別な意味を持っています。
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は、コード内の印刷出力を行う時間が遅くなることはありません。