動態規劃初步 硬幣問題

2021-10-04 05:48:06 字數 1606 閱讀 4563

問題描述:現有面值為3,4,5的三種硬幣(每種硬幣可以重複使用),現在去商店買乙個東西要x元,問如何用最少的硬幣付清,而不需要對方找錢,如果無法用手中的硬幣恰好湊出x則列印-1.

樣例:輸入: 1   2   3  6

輸出:-1 -1   1  2

分析:有乙個很直覺的思路就是先盡量用大的硬幣,然後用小的硬幣,舉個栗子:這個題中13元可以分解為先用乙個5元,再用乙個5元,此時發現再用乙個3元硬幣就行了。哦豁,妙哇,完美解決了。

別急,舉個反例看看:27元用2,5,7三種硬幣,你會覺得用3個7再用3個2,一共6個硬幣就行了嗎。其實呢,最少的是1個7和4個5,才5個硬幣。這說明貪心策略只是區域性最優解而不是全域性最優解,而且是暴力,不太具有普遍性。

如果用遞迴法的話,會發現有很多重複計算,而且空間開銷大,也欠妥。

下面列出這道題的動態規劃思路步驟:

1、可以確定a1+a2+a3+...+ak=x元一定成立,且一定有最後的一枚面值為ak的硬幣,而且除掉最後一枚硬幣前面的所有硬幣面值加起來一定是x-ak元

注意:不需要知道前面k-1個硬幣具體是怎麼樣的,甚至不需要知道k和ak,但是可以確定前面的硬幣拼了x-ak元

2、最優子結構:先不看最後乙個ak硬幣,而是要確保前面的x-ak元的拼湊方法一定是用硬幣最少的!!!

設f(x)=湊出x元最少用的硬幣數

這道題不難推出:f(x)=min;

本題的具體資料:

f(0)   f(1)      f(2)     f(3)     f(4)   f(5)   f(6)  f(7)   f(8)  f(9) f(10) f(11)......

需要的硬幣數 0      max    max     1       1        1       2     2    . 2     2     2      3   ....

解釋:2=1*2;3=1*3;4=1*4;5=1*5;6=3*2;7=3+4;8=3+5或者4+4(但都是兩枚) ;9=5+4;11=4+4+3(3枚)

初始:b[0]=0,0元不用硬幣

依次算出b[1],b[2],b[3]。。。其中後面的是通過前面的推出來的,不要從大往小推(b[n],b[n-1]...b[2],b[1]),至於為什麼可以仔細想想。

**寫的有點雜。。。主要是確定狀態轉移方程中最優子結構時用了輔助變數fl和min

#include#define max 100000

int b[10000];

int main()

;int n,i,j;

scanf("%d",&n)//輸入總**

b[0]=0;//初始化0元不需要硬幣

for(i=1;i<=n;i++)//每次迴圈確定乙個b[i]的值,b[i]要麼是max(湊不出硬幣),要麼是乙個比較小的數

if(i-a[j]>=0&&fl)

if(b[n]>=max)//這是不能湊出硬幣的情況列印-1表示

printf("-1");

else

printf("%d",b[n]);

}

動態規劃 硬幣問題

這是乙個固定重點的最長路和最短路問題,可用動態規劃問題來求解 代表硬幣總值,n代表硬幣總數,v陣列儲存硬幣各個面值,d代表從i出發到結點0的路徑的最長路徑長度或最短路徑長度 vis代表是否訪問過該結點 int n,s,v maxn d maxn vis maxn int dpmax int s re...

動態規劃 硬幣問題

2013 07 11 03 17 5610人閱讀收藏 舉報 演算法和資料結構學習 79 最少硬幣問題 假設有3種不同的硬幣,幣值分別是coinvalue 每一種硬幣的數量是有限的,分別是coinnum 給定乙個數值target 18,找出一種硬幣數最少的方法,輸出最少的硬幣數。思路 動態規劃。問題定...

動態規劃 硬幣問題

問題描述 輸入總金額n,硬幣不同價值的種類m,m種硬幣的面值 例如 15 6 1 2 7 8 12 50 輸出湊成n最少的硬幣數 1 貪心演算法 每次都選擇面值最大的。問題在於,求出來的並不是最優解,上例中,用貪心解出來的結果為3 1,2,12 而實際為2 7,8 include includeus...