動態規劃 硬幣找零思路

2021-09-26 06:57:45 字數 2696 閱讀 1523

硬幣找零問題,有兩種。一種用貪心解決,一種用動態規劃解決。

問題1:假設我們有 v1,v2,……,vn(單位是元)這些幣值的硬幣,它們的張數分別是 c1、c2、…, cn。我們現在要用這些錢來找零 w元,最少要用多少張紙幣呢?

問題2:假設我們有幾種不同幣值的硬幣 v1,v2,……,vn(單位是元)。如果我們要支付 w 元,求最少需要多少個硬幣。比如,我們有 3 種不同的硬幣,1 元、3 元、5 元,我們要支付 9 元,最少需要 3 個硬幣(3 個 3 元的硬幣)。

問題1有乙個限制條件是不同面額的硬幣的張數是有限制的,而問題2中沒有這個限制。

問題1解決用貪心。選擇小於w的,面值最大的硬幣,來付錢。

問題2解決用動態規劃。至於為什麼不用貪心,我也不大明白。接下來重點描述問題2的解決方法。

因為多次用了回溯法,所以很自然想到,每次決定一種硬幣,使用一種數量,會產生什麼狀態。

例如w=9,

在第0階段,我可以決定1元,使用0張,產生一種狀態:支付0元;1元,使用1張,產生一種狀態:支付1元;1元,使用2張,產生一種狀態:支付2元…

在第1階段,我可以決定3元,使用0張,基於上一步的狀態產生新的狀態:支付0、1、2…元;使用1張,基於上一步的狀態產生新的狀態:1+3、2+3…

當支付金額等於9的時候,比較最少使用了多少個硬幣。

public class coinchange ;

private int n = coins.length;

//總金額

private int total = 9;

private int mincount = integer.max_value;

private void f (int i,int coincount, int sum)

if(sum>total)

if(i==n)

int maxcount = (total - sum)/coins[i];

system.out.println(maxcount);

for(int j=0;j<=maxcount;j++)

}public int findcoincount()

}

我們還可以換一種思路。我們按照支付金額分階段。

我們硬幣種類有1 元、3 元、5 元。設f(9)表示想要支付9元最少需要幾個硬幣。f(9)可以從f(9-1)、f(9-3)、f(9-5)三個狀態過來,分別在這三個狀態+1,選擇最低值就是f(9)最少需要支付多少個硬幣。

定義狀態轉移公式:

f (s

)=mi

ni=0

,1

,2...n−

1(f(

s−ci

))+1

f(s)=min_(f(s-c_i))+1

f(s)=m

ini=

0,1,

2...

n−1​

(f(s

−ci​

))+1

,subject to s−c

i>=0

s-c_i>=0

s−ci

​>=0

f (0

)=

0f(0)=0

f(0)=0

f (s

)=−1

f(s)=-1

f(s)=−

1,when n=0

n=0n=

0 上一種回溯中是以每次選擇一種硬幣作為階段。這次是每次支付夠1元,2元,3元…n元,為階段

public class coinchangev3 ;

private int n = coins.length;

//總金額

private int total = 9;

private int f (int total);

private int n = coins.length;

//總金額

private int total = 9;

private int f (int total,int memory){

if(n==0) return -1;

if(total == 0) return 0;

if(memory[total] !=0) return memory[total];

int mincount = integer.max_value;

for(int i=0;i根據動態轉移方程計算。

public int findcoincountdp(){

int max = total+1;

int dp = new int[total+1];

arrays.fill(dp,max);

dp[0] = 0;

for(int i=1;i<=total;i++){

for(int j=0;i放在最後的一點體會。將問題抽象為多階段決策問題,要分清楚是按照什麼分階段。一般來講是按照目標指標分階段。例如支付9元最少需要多少個硬幣,分階段為支付8元最少需要多少個硬幣,支付7元最少需要多少個硬幣…。例如從(0,0)走到(n-1,n-1)最少需要多少步,目標是(n-1,n-1),前一步可以是(n-1,n-2)或者(n-2,n-1),知道他們的最少步數+1,就是目標值,所以可以按照到達的座標分階段。

按照某個指標做分階段,回溯法列舉的時候不一定與此相關。回溯法列舉的時候,列舉的是選項。例如不同面值的硬幣,不同的前進方向。

動態規劃 硬幣找零

時間限制 1000 ms 記憶體限制 65535 kb 描述在現實生活中,我們經常遇到硬幣找零的問題,例如,在發工資時,財務人員就需要計算最少的找零硬幣數,以便他們能從銀行拿回最少的硬幣數,並保證能用這些硬幣發工資。我們應該注意到,人民幣的硬幣系統是 100,50,20,10,5,2,1,0.5,0...

硬幣找零問題(動態規劃)

給定指定的硬幣種類,面值為 1,3,5 在此具體化些 給定所找零的錢數 sum,給出最少的硬幣找零數,每個種類的硬幣無限使用。看到這問題,當時我想到用貪心演算法來求解,最後求解方案因為巧合對了,後來在網上看到動態規劃的題目,才知道貪心演算法得不到最優解,比如 給定 面值為 1,3,4,給定找零數為 ...

動態規劃 最小硬幣找零

用的硬幣面額d1 dn 及其數量,找出有多少種找零方法。最少硬幣找零問題是給出要找零的錢數,以及可用的硬幣面額d1 dn 及其數量,找到所需的最少的硬幣個數。最小硬幣找零 function mincoinchange coins var cache this.makechange function ...