動態規劃 最少硬幣問題

2022-09-15 08:42:14 字數 1730 閱讀 2402

time limit: 1000 ms memory limit: 65536 kib

problem description

設有n種不同面值的硬幣,各硬幣的面值存於陣列t[1:n]中。現要用這些面值的硬幣來找錢。可以使用的各種面值的硬幣個數存於陣列coins[1:n]中。

對任意錢數0≤m≤20001,設計乙個用最少硬幣找錢m的方法。

對於給定的1≤n≤10,硬幣面值陣列t和可以使用的各種面值的硬幣個數陣列coins,以及錢數m,0≤m≤20001,計算找錢m的最少硬幣數。

input

輸入資料第一行中只有1個整數給出n的值,第2行起每行2個數,分別是t[j]和coins[j]。最後1行是要找的錢數m。

output

輸出資料只有乙個整數,表示計算出的最少硬幣數。問題無解時輸出-1。

sample input

3

1 32 3

5 318

sample output

5

hint

source

演算法思路:

這題採用"動態規劃"演算法,將大問題轉換為小問題,且一步步記錄上一步的結果。

與"揹包問題"的對比與分析:

「揹包」中給出了"損失"與"收益",但其都是對於單個物品,求最大收益;「硬幣」中給出的是"收益"、"個數"與"最終收益",求最小組合。

可以看出,如果對於"硬幣問題",要採用動態規劃的話,依照"一步步走的原則",至少要進行拆分,比如 5 個 2,要拆分成 5 、5,先計算第乙個5,之後再計算第二個5。

演算法設計:

依舊採用一維陣列 "dp[目標面額]=最小需求個數" 來儲存最終結果。

我們將所有硬幣依次拆分成單個,dp[目標面額] = min(dp[目標面額-當前面額]+1,dp[目標面額]),前乙個是將該面額放入該組合中,後乙個是不採用當前面額,選取數值最小的。

演算法注意事項:

前兩層迴圈是將面額拆分,注意邊界是否帶等號。

dp[k]陣列初始化時,除k=0外所有數值設定為無窮大,因為當需求為0時,其組合數本來就為0種,如果這個也設定為無窮大,則無法計算了。

源**:

1

//演算法.cpp : 此檔案包含 "main" 函式。程式執行將在此處開始並結束。2//

34 #include "

pch.h

"5 #include 6 #include 7

#define inf 0x3f3f3f3f

8using

namespace

std;910

intmain()

1920 cin >>des;

21 dp[0] = 0;22

23//

演算法注意邊界是否帶等號

24for (int i = 0; i < n; i++)

25for (int j = 1; j <= coin[i]; j++)

26for (int k = des; k >= t[i]; k--)

27 dp[k] = min(dp[k], dp[k - t[i]] + 1

); 28

29 cout << (dp[des]1) <31

最少硬幣問題 動態規劃

需要找零x元,有n種面值硬幣,求找零最少需要硬幣個數的方法。這題如果用貪心演算法做,很可能無法得到最優解甚至無法無法找零,比如要找零11元,有三種硬幣,最優解是,用貪心就會先用10塊錢去消耗,那這題就無法完成。所以這題用動態規劃最合適,利用遞推和快取,動態規劃將問題拆分成若干個子問題,通過子問題的最...

動態規劃 最少硬幣問題

problem description 設有n種不同面值的硬幣,各硬幣的面值存於陣列t 1 n 中。現要用這些面值的硬幣來找錢。可以使用的各種面值的硬幣個數存於陣列coins 1 n 中。對任意錢數0 m 20001,設計乙個用最少硬幣找錢m的方法。對於給定的1 n 10,硬幣面值陣列t和可以使用的...

最少硬幣問題 (動態規劃)

最少硬幣問題 time limit 1000 ms memory limit 65536 kib problem description 設有n種不同面值的硬幣,各硬幣的面值存於陣列t 1 n 中。現要用這些面值的硬幣來找錢。可以使用的各種面值的硬幣個數存於陣列coins 1 n 中。對任意錢數0 ...