java動(dòng)態(tài)規(guī)劃算法——硬幣找零問(wèn)題實(shí)例分析
本文實(shí)例講述了java動(dòng)態(tài)規(guī)劃算法——硬幣找零問(wèn)題。分享給大家供大家參考,具體如下:
問(wèn)題描述
現(xiàn)在有3種硬幣分別為:1元,5元,10元,現(xiàn)在給你63元,讓你全部換成硬幣,求出最小硬幣數(shù)量,也就是說(shuō),怎么用最少的硬幣數(shù)湊成63元。
分析問(wèn)題
解決這個(gè)問(wèn)題,我們可以將這個(gè)大問(wèn)題分成若干個(gè)小問(wèn)題,自下而上解決問(wèn)題。
1元對(duì)應(yīng)的最小硬幣數(shù)是1
2元對(duì)應(yīng)的最小硬幣數(shù)是2
3元對(duì)應(yīng)的最小硬幣數(shù)是3
4元對(duì)應(yīng)的最小硬幣數(shù)是4
……
63元對(duì)應(yīng)的最小硬幣數(shù)是XXX
假設(shè)我們將前邊計(jì)算出的金額對(duì)應(yīng)的最小硬幣數(shù)像備忘錄一樣記錄下來(lái),那么后邊金額對(duì)應(yīng)的最小硬幣數(shù)的就好說(shuō)了,為什么?
舉例:假設(shè)你要求63的最小硬幣數(shù),那么你需要這樣計(jì)算:63-1=62、63-5=58、63-10=53。假設(shè)62、58、53對(duì)應(yīng)的最小硬幣數(shù)已經(jīng)被你記錄在了備忘錄數(shù)組。這時(shí)候你只需要找出62、58、53中誰(shuí)對(duì)應(yīng)的最小硬幣數(shù)最小,然后加1,就是63對(duì)應(yīng)的最小硬幣數(shù)。因?yàn)?3比62、58、53都大,最好的情況無(wú)非就是在62、58、53中找出最小的一種情況加1,這就是最優(yōu)解!
按照這種備忘錄思想,我們進(jìn)行編程。首先將我們要處理的數(shù)據(jù)轉(zhuǎn)換成數(shù)組和必要參數(shù)。
int[] coins = { 1 , 5 , 10 }; //硬幣面額數(shù)組
int adm = 63; //要求的金額
int[] money = new int[63+1]; //金額數(shù)組,也就是備忘錄數(shù)組
說(shuō)明:money數(shù)組就是備忘錄數(shù)組,例如:money[0]對(duì)應(yīng)0,money[1]對(duì)應(yīng)1,money[2]對(duì)應(yīng)2……
接下來(lái),將我們上邊的解題思路抽象成函數(shù),函數(shù)中無(wú)非就是:循環(huán),判斷,賦值……如何利用這些邏輯語(yǔ)句,將我們的思路描述出來(lái),這是最難的,因?yàn)橐龅降嗡宦闆r都要考慮周全,一步錯(cuò)結(jié)果就錯(cuò),這需要長(zhǎng)久鍛煉抽象邏輯思維。我比較習(xí)慣的方式是邊看代碼,邊關(guān)聯(lián)結(jié)題思路,然后模仿,代碼中有注釋?zhuān)蠹疫吙催叿治霭桑?/p>
public static void main(String[] args) {
int[] coins = {1,5,10};
int money = 63;
changeMoney(coins,money);
}
/**
* 硬幣找零算法,備忘錄方法
* @param coins 硬幣面額數(shù)組
* @param money 目標(biāo)金額
*/
public static void changeMoney( int[] coins , int money ) {
//備忘錄數(shù)組,一一對(duì)應(yīng)
int[] memo = new int[money + 1];
//0元對(duì)應(yīng)的最小硬幣數(shù)是0
memo[0] = 0;
System.out.println( "金額\t" + "對(duì)應(yīng)的最小硬幣數(shù)" );
//遍歷備忘錄數(shù)組,為每個(gè)金額記錄他的最小硬幣數(shù),我們從1元開(kāi)始
for( int currentMoney = 1 ; currentMoney <= money ; currentMoney++ ) {
//默認(rèn)最小硬幣數(shù)就是當(dāng)前金額的本身
//舉例:63元最多就是63個(gè)1元的硬幣唄
int minCoins = currentMoney;
//遍歷硬幣面額數(shù)組,找到前邊所能找到的最小硬幣數(shù)加1
for( int coinKind = 0 ; coinKind < coins.length ; coinKind++ ) {
//只有當(dāng)前金額大于等于某個(gè)硬幣面額的時(shí)候才可以用這種方法
//舉例:5-1=4,5-5=0,5-10=-5,我們沒(méi)有-5元好吧……
if( currentMoney >= coins[coinKind] ) {
//我們?cè)趥渫浿胁檎抑暗慕痤~對(duì)應(yīng)的最小硬幣數(shù)
//如果能查到就在它的基礎(chǔ)上加1
int tempCoins = memo[currentMoney - coins[coinKind]] + 1;
//找到幾種情況中最小的硬幣數(shù)
//舉例:63元 tempConis
//可以是memo[63-1]+1、memo[63-5]+1、memo[63-10]+1
//我們要找到最小的
if( tempCoins < minCoins ) {
minCoins = tempCoins;
}
}
}
//找到當(dāng)前金額對(duì)應(yīng)的最小硬幣數(shù),我們將它記錄在備忘錄中
memo[currentMoney] = minCoins;
System.out.println( currentMoney + "\t" + memo[currentMoney] );
}
}
運(yùn)行結(jié)果
金額 對(duì)應(yīng)的最小硬幣數(shù)
1 1
2 2
3 3
4 4
5 1
6 2
7 3
8 4
9 5
10 1
11 2
12 3
13 4
14 5
15 2
16 3
17 4
18 5
19 6
20 2
21 3
22 4
23 5
24 6
25 3
26 4
27 5
28 6
29 7
30 3
31 4
32 5
33 6
34 7
35 4
36 5
37 6
38 7
39 8
40 4
41 5
42 6
43 7
44 8
45 5
46 6
47 7
48 8
49 9
50 5
51 6
52 7
53 8
54 9
55 6
56 7
57 8
58 9
59 10
60 6
61 7
62 8
63 9
更多關(guān)于java算法相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對(duì)大家java程序設(shè)計(jì)有所幫助。
- Java動(dòng)態(tài)規(guī)劃之硬幣找零問(wèn)題實(shí)現(xiàn)示例
- Java使用動(dòng)態(tài)規(guī)劃算法思想解決背包問(wèn)題
- Java實(shí)現(xiàn)動(dòng)態(tài)規(guī)劃背包問(wèn)題
- java背包問(wèn)題動(dòng)態(tài)規(guī)劃算法分析
- 背包問(wèn)題-動(dòng)態(tài)規(guī)劃java實(shí)現(xiàn)的分析與代碼
- Java面試之動(dòng)態(tài)規(guī)劃與組合數(shù)
- Java動(dòng)態(tài)規(guī)劃之編輯距離問(wèn)題示例代碼
- Java動(dòng)態(tài)規(guī)劃之硬幣找零問(wèn)題實(shí)現(xiàn)代碼
- Java動(dòng)態(tài)規(guī)劃之丑數(shù)問(wèn)題實(shí)例講解
相關(guān)文章
使用JMX監(jiān)控Zookeeper狀態(tài)Java API
今天小編就為大家分享一篇關(guān)于使用JMX監(jiān)控Zookeeper狀態(tài)Java API,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03
Java springboot 配置文件與多環(huán)境配置與運(yùn)行優(yōu)先級(jí)
這篇文章主要介紹了Java springboot如何配置文件,進(jìn)行多環(huán)境配置,以及運(yùn)行優(yōu)先級(jí),感興趣的小伙伴可以借鑒一下2023-04-04
詳解如何獲取java中類(lèi)的所有對(duì)象實(shí)例
如何在運(yùn)行時(shí)獲取一個(gè)Java類(lèi)的所有對(duì)象實(shí)例呢,本文給大家介紹一種底層實(shí)現(xiàn)的方式,基于jvmti,代碼用C++實(shí)現(xiàn),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-10-10
SpringBoot實(shí)現(xiàn)無(wú)限級(jí)評(píng)論回復(fù)的項(xiàng)目實(shí)踐
本文主要介紹了SpringBoot實(shí)現(xiàn)無(wú)限級(jí)評(píng)論回復(fù)的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03
java中PriorityBlockingQueue的入隊(duì)知識(shí)點(diǎn)總結(jié)
在本篇文章里小編給大家整理一篇關(guān)于java中PriorityBlockingQueue的入隊(duì)知識(shí)點(diǎn)總結(jié)內(nèi)容,有需要的朋友們可以學(xué)習(xí)下。2021-01-01
Mybatis映射文件根標(biāo)簽與子標(biāo)簽示例講解
這篇文章主要介紹了Mybatis映射文件根標(biāo)簽與子標(biāo)簽,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-01-01
JetBrains?產(chǎn)品輸入激活碼?Key?is?invalid?完美解決方案
JetBrains?系列產(chǎn)品(IDEA、Pycharm?等)使用本站破解教程?(opens?new?window),在輸入激活碼時(shí),部分小伙伴反應(yīng)說(shuō)提示?Key?is?invalid?無(wú)法激活,今天小編給大家分享完美解決方案,感興趣的朋友跟隨小編一起看看吧2022-11-11
Java使用自定義注解+反射實(shí)現(xiàn)字典轉(zhuǎn)換代碼實(shí)例
這篇文章主要介紹了Java使用自定義注解+反射實(shí)現(xiàn)字典轉(zhuǎn)換代碼實(shí)例,注解是一種能被添加到j(luò)ava代碼中的元數(shù)據(jù),類(lèi)、方法、變量、參數(shù)和包都可以用注解來(lái)修飾,注解對(duì)于它所修飾的代碼并沒(méi)有直接的影響,需要的朋友可以參考下2023-09-09
springboot簡(jiǎn)單實(shí)現(xiàn)單點(diǎn)登錄的示例代碼
本文主要介紹了springboot簡(jiǎn)單實(shí)現(xiàn)單點(diǎn)登錄的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
Java高級(jí)之HashMap中的entrySet()方法使用
這篇文章主要介紹了Java高級(jí)之HashMap中的entrySet()方法使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03

