通俗的方式解釋“零錢兌換”問題

“零錢兌換”是一道經典的算法題目,其主要問題是:給定不同面額的硬幣和一個總金額,求出湊成總金額所需的最少硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回-1。

解題思路

  1. 動態規劃:使用動態規劃是解決零錢兌換問題的常用方法。定義一個數組dp,其中dp[i]表示湊成金額i所需的最少硬幣個數。
  2. 狀態轉移方程:對于每個金額i,遍歷所有硬幣面額coin,如果i >= coin,則dp[i] = min(dp[i], dp[i - coin] + 1)
  3. 初始化dp[0] = 0,因為湊成金額0不需要任何硬幣。對于其他金額,可以初始化為一個較大的數(如amount + 1),表示初始時無法湊成該金額。
  4. 結果判斷:最終dp[amount]即為所求,如果dp[amount]仍為初始值,則表示無法湊成總金額,返回-1。

示例代碼(C++)

#include <vector>
#include <algorithm>
using namespace std;int coinChange(vector<int>& coins, int amount) {vector<int> dp(amount + 1, amount + 1); // 初始化為一個較大的數dp[0] = 0; // 湊成金額0不需要任何硬幣for (int i = 1; i <= amount; ++i) {for (int coin : coins) {if (i >= coin) {dp[i] = min(dp[i], dp[i - coin] + 1);}}}return dp[amount] > amount ? -1 : dp[amount];
}

說明

  • 輸入coins是一個整數數組,表示不同面額的硬幣;amount是一個整數,表示總金額。
  • 輸出:返回湊成總金額所需的最少硬幣個數,如果無法湊成,則返回-1。

這道題考察了動態規劃的思想和實現能力,是面試中常見的算法題。

狀態轉移方程不太懂

好的,我們來詳細解釋一下“零錢兌換”問題中的狀態轉移方程

問題背景

假設我們有若干種硬幣,每種硬幣有不同的面額。現在需要湊出一個總金額 amount,目標是用最少的硬幣數量湊出這個金額。

動態規劃中的狀態定義

在動態規劃中,我們需要定義一個狀態來表示問題的子問題。對于零錢兌換問題,我們定義:

  • dp[i] 表示湊成金額 i 所需的最少硬幣數量。

狀態轉移方程的含義

狀態轉移方程是動態規劃的核心,它描述了如何從已知的子問題狀態推導出當前問題的狀態。

對于零錢兌換問題,狀態轉移方程是:
dp[i] = min(dp[i], dp[i - coin] + 1)

這個方程的意思是:

  • 如果我們想湊成金額 i,可以嘗試用一個面額為 coin 的硬幣。
  • 如果用了這個硬幣,那么剩下的金額就是 i - coin
  • 我們已經知道湊成金額 i - coin 所需的最少硬幣數量是 dp[i - coin]
  • 因此,湊成金額 i 的硬幣數量可以是 dp[i - coin] + 1+1 是因為我們多用了一個硬幣)。
  • 但是,湊成金額 i 的方法可能有多種(比如可以用不同面額的硬幣),所以我們要取所有可能方法中的最小值。

具體例子

假設硬幣面額為 [1, 2, 5],目標金額是 11

初始化

我們先初始化一個數組 dp,長度為 amount + 1,并將所有值設為一個較大的數(比如 amount + 1),表示初始時認為湊不出這些金額。同時,dp[0] = 0,因為湊成金額 0 不需要任何硬幣。

計算過程

我們逐步計算每個金額的最少硬幣數:

  1. 計算 dp[1]

    • 嘗試用面額為 1 的硬幣:dp[1 - 1] + 1 = dp[0] + 1 = 0 + 1 = 1
    • 因此,dp[1] = 1
  2. 計算 dp[2]

    • 嘗試用面額為 1 的硬幣:dp[2 - 1] + 1 = dp[1] + 1 = 1 + 1 = 2
    • 嘗試用面額為 2 的硬幣:dp[2 - 2] + 1 = dp[0] + 1 = 0 + 1 = 1
    • 因此,dp[2] = min(2, 1) = 1
  3. 計算 dp[3]

    • 嘗試用面額為 1 的硬幣:dp[3 - 1] + 1 = dp[2] + 1 = 1 + 1 = 2
    • 嘗試用面額為 2 的硬幣:dp[3 - 2] + 1 = dp[1] + 1 = 1 + 1 = 2
    • 因此,dp[3] = min(2, 2) = 2
  4. 計算 dp[4]

    • 嘗試用面額為 1 的硬幣:dp[4 - 1] + 1 = dp[3] + 1 = 2 + 1 = 3
    • 嘗試用面額為 2 的硬幣:dp[4 - 2] + 1 = dp[2] + 1 = 1 + 1 = 2
    • 因此,dp[4] = min(3, 2) = 2
  5. 計算 dp[5]

    • 嘗試用面額為 1 的硬幣:dp[5 - 1] + 1 = dp[4] + 1 = 2 + 1 = 3
    • 嘗試用面額為 2 的硬幣:dp[5 - 2] + 1 = dp[3] + 1 = 2 + 1 = 3
    • 嘗試用面額為 5 的硬幣:dp[5 - 5] + 1 = dp[0] + 1 = 0 + 1 = 1
    • 因此,dp[5] = min(3, 3, 1) = 1

……以此類推,直到計算出 dp[11]

總結

狀態轉移方程 dp[i] = min(dp[i], dp[i - coin] + 1) 的含義是:

  • 對于每個金額 i,嘗試用每一種硬幣 coin
  • 如果用了這個硬幣,那么剩下的金額是 i - coin,而湊成 i - coin 的最少硬幣數是已知的(dp[i - coin])。
  • 因此,湊成金額 i 的硬幣數可以是 dp[i - coin] + 1
  • 最后取所有可能方法中的最小值,作為湊成金額 i 的最少硬幣數。

希望這個解釋能幫助你更好地理解狀態轉移方程!

我還是不理解

好的,我來用更通俗的方式解釋“零錢兌換”問題。


問題背景

假設你是一名收銀員,顧客需要找零,你手上有不同面額的硬幣。你的任務是用最少的硬幣數量湊出顧客需要的零錢金額。

舉個例子

假設你手上有以下幾種硬幣:

  • 1元硬幣
  • 3元硬幣
  • 4元硬幣

現在顧客需要找零 10元,你會怎么湊呢?


思考過程

  1. 目標:用最少的硬幣湊出10元。
  2. 方法:你可以嘗試不同的組合:
    • 用10個1元硬幣(10個硬幣)
    • 用3個3元硬幣 + 1個1元硬幣(4個硬幣)
    • 用2個4元硬幣 + 2個1元硬幣(4個硬幣)
    • 用1個4元硬幣 + 2個3元硬幣(3個硬幣)

經過比較,你會發現 1個4元硬幣 + 2個3元硬幣 是最優解,只需要 3個硬幣


零錢兌換問題的核心

  1. 輸入

    • 一個硬幣數組,比如 [1, 3, 4],表示你手上的硬幣面額。
    • 一個目標金額,比如 10,表示需要湊出的金額。
  2. 輸出

    • 返回最少需要的硬幣數量。如果無法湊出目標金額,返回 -1
  3. 難點

    • 你不能簡單地從最大的硬幣開始湊,因為可能無法湊出目標金額。比如,目標金額是 6元,硬幣面額是 [4, 3, 1],如果你先用一個4元硬幣,剩下的2元就無法湊出(因為沒有2元硬幣)。

動態規劃的思路

動態規劃是一種分步解決問題的方法,它把大問題拆成小問題,逐步求解。

  1. 定義狀態

    • 假設 dp[i] 表示湊出金額 i 所需的最少硬幣數量。
  2. 狀態轉移

    • 假設你已經知道湊出金額 i - coin 所需的最少硬幣數量(dp[i - coin]),那么加上一個面額為 coin 的硬幣,就可以湊出金額 i
    • 所以,dp[i] = min(dp[i], dp[i - coin] + 1),意思是:湊出金額 i 的最少硬幣數,要么是之前已經計算好的值,要么是湊出金額 i - coin 的硬幣數加1。
  3. 初始化

    • dp[0] = 0,因為湊出金額0不需要任何硬幣。
    • 其他金額可以初始化為一個很大的數(比如 amount + 1),表示目前無法湊出。
  4. 最終結果

    • 如果 dp[amount] 仍然是初始值(比如 amount + 1),說明無法湊出目標金額,返回 -1
    • 否則,返回 dp[amount]

用例子解釋動態規劃

假設硬幣面額是 [1, 3, 4],目標金額是 6,我們逐步計算 dp 數組:

金額(i)0123456
dp[i]0121122
  • 金額0dp[0] = 0,湊出金額0不需要硬幣。
  • 金額1:只能用1個1元硬幣,所以 dp[1] = 1
  • 金額2:只能用2個1元硬幣,所以 dp[2] = 2
  • 金額3:可以用3個1元硬幣(dp[3] = dp[0] + 1 = 1),也可以用1個3元硬幣(dp[3] = 1)。
  • 金額4:可以用4個1元硬幣(dp[4] = dp[0] + 1 = 1),也可以用1個4元硬幣(dp[4] = 1)。
  • 金額5:可以用5個1元硬幣(dp[5] = dp[0] + 1 = 2),也可以用1個3元硬幣 + 2個1元硬幣(dp[5] = dp[2] + 1 = 2)。
  • 金額6:可以用6個1元硬幣(dp[6] = dp[0] + 1 = 2),也可以用2個3元硬幣(dp[6] = dp[0] + 2 = 2)。

最終,湊出金額6最少需要2個硬幣。


總結

零錢兌換問題的核心是用最少的硬幣湊出目標金額。動態規劃通過逐步計算每個金額所需的最少硬幣數,最終得到答案。希望這個解釋能幫助你理解!

這回我終于懂了!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/896943.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/896943.shtml
英文地址,請注明出處:http://en.pswp.cn/news/896943.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

GBT32960 協議編解碼器的設計與實現

GBT32960 協議編解碼器的設計與實現 引言 在車聯網領域&#xff0c;GBT32960 是一個重要的國家標準協議&#xff0c;用于新能源汽車與監控平臺之間的數據交互。本文將詳細介紹如何使用 Rust 實現一個高效可靠的 GBT32960 協議編解碼器。 整體架構 編解碼器的核心由三個主要組…

Halcon 車牌識別-超精細教程

車牌示例 流程: 讀取圖片轉灰度圖閾值分割,找車牌內容將車牌位置設置變換區域形狀找到中心點和弧度利用仿射變換,斜切車牌旋轉轉正,把車牌摳出來利用形態學操作拼接車牌號數字訓練ocr開始識別中文車牌 本文章用到的算子(解析) Halcon 算子-承接車牌識別-CSDN博客 rgb1_to_gray…

UDP透傳程序

UDP透傳程序 本腳本用于在 設備 A 和 設備 B 之間建立 UDP 數據轉發橋梁&#xff0c;適用于 A 和 B 設備無法直接通信的情況。 流程&#xff1a; A --> 電腦 (中繼) --> B B --> 電腦 (中繼) --> A 需要修改參數&#xff1a; B_IP “192.168.1.123” # 設備 B 的…

Holtek HT82V42A深度解析:CCD/CIS信號處理的集成化解決方案

——簡化圖像采集系統設計的終極利器 一、HT82V42A核心參數與外設資源 HT82V42A是Holtek專為圖像傳感器信號處理設計的模擬前端芯片&#xff0c;集成CCD/CIS信號處理與LED驅動功能&#xff0c;關鍵參數如下&#xff1a; 參數類別規格說明信號處理通道單通道CCD/CIS模擬信號輸…

詳細分析KeepAlive的基本知識 并緩存路由(附Demo)

目錄 前言1. 基本知識2. Demo2.1 基本2.2 拓展2.3 終極 3. 實戰 前言 &#x1f91f; 找工作&#xff0c;來萬碼優才&#xff1a;&#x1f449; #小程序://萬碼優才/r6rqmzDaXpYkJZF 基本知識推薦閱讀&#xff1a;KeepAlive知識點 從實戰中學習&#xff0c;源自實戰中vue路由的…

記一次誤禁用USB導致鍵盤鼠標失靈的修復過程

背景說明 在電腦上插入了一個USB hub&#xff0c;然后彈窗提示&#xff1a;“集線器端口上出現電涌”&#xff0c;點開讓選擇“重置”或者“關閉”&#xff0c;不小心點了關閉&#xff0c;結果這個usb口就被關了&#xff0c;再插任何東西都沒反應&#xff0c;找了很多辦法都恢…

小米手機如何錄制屏幕?手機、電腦屏幕錄制方法分享

大家最近有沒有遇到想記錄手機屏幕操作的情況&#xff1f; 比如精彩的游戲瞬間、有趣的視頻教程&#xff0c;或者需要錄制屏幕來制作演示材料。小米手機在這方面可是個好幫手&#xff0c;今天就來給你好好嘮嘮&#xff0c;小米手機如何錄制屏幕&#xff0c;以及后續如何處理這…

如何將JAR交由Systemctl管理?

AI越來越火了&#xff0c;我們想要不被淘汰就得主動擁抱。推薦一個人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;最重要的屌圖甚多&#xff0c;忍不住分享一下給大家。點擊跳轉到網站 廢話不多說&#xff0c;進入正題。下面開始說如何使用 systemctl…

chrome Vue.js devtools 提示不支持該擴展組件,移除

可能是版本不兼容&#xff0c;可以重新安裝&#xff0c;推薦網址極簡插件官網_Chrome插件下載_Chrome瀏覽器應用商店 直接搜索vue&#xff0c;下載舊版&#xff0c;vue2、vue3都支持&#xff0c;上面那個最新版本試了下&#xff0c;vue2的肯定是不能用

【RabbitMQ】RabbitMQ的核心概念與七大工作模式

&#x1f525;個人主頁&#xff1a; 中草藥 &#x1f525;專欄&#xff1a;【中間件】企業級中間件剖析 在現代分布式系統和微服務架構中&#xff0c;消息隊列&#xff08;Message Queue&#xff09; 是解決服務間通信、系統解耦和流量削峰的關鍵技術之一。而 RabbitMQ 作為一…

SQLAlchemy系列教程:理解SQLAlchemy元數據

SQLAlchemy是Python開發人員的強大ORM工具。SQLAlchemy中的元數據是對象-關系映射配置的集合&#xff0c;允許開發人員無縫地定義和使用數據庫模式。 使用元數據 SQLAlchemy中的元數據充當各種數據庫描述符&#xff08;如表、列和索引&#xff09;的容器。這使開發人員能夠通…

MacDroid for Mac v2.3 安卓手機文件傳輸助手 支持M、Intel芯片 4.7K

MacDroid 是Mac毒搜集到的一款安卓手機文件傳輸助手&#xff0c;在Mac和Android設備之間傳輸文件。您只需要將安卓手機使用 USB 連接到 Mac 電腦上即可將安卓設備掛載為本地磁盤&#xff0c;就像編輯mac磁盤上的文件一樣編輯安卓設備上的文件&#xff0c;MacDroid支持所有 Andr…

Android+SpringBoot的老年人健康飲食小程序平臺

感興趣的可以先收藏起來&#xff0c;還有大家在畢設選題&#xff0c;項目以及論文編寫等相關問題都可以給我留言咨詢&#xff0c;我會一一回復&#xff0c;希望幫助更多的人。 系統介紹 我將從經濟、生活節奏、技術融合等方面入手&#xff0c;詳細闡述居家養老管理模式興起的…

【星云 Orbit ? STM32F4】10. 在串口接收中斷里即時解析數據頭的程序框架

【星云 Orbit ? STM32F4】10. 串口中斷中即時解析數據頭的程序開發&#xff1a;實現高效實時數據處理 摘要 在嵌入式開發中&#xff0c;串口中斷處理是實現高效實時數據傳輸的關鍵技術之一。本文將詳細介紹如何在STM32F407微控制器上開發一個在串口接收中斷中即時解析數據頭的…

數據倉庫的特點

數據倉庫的主要特點可以概括為&#xff1a;面向主題、集成性、非易失性、時變性、高性能和可擴展性、支持復雜查詢和分析、分層架構以及數據質量管理。 1. 面向主題&#xff08;Subject-Oriented&#xff09; 數據倉庫是面向主題的&#xff0c;而不是面向事務的。這意味著數據…

SAP MDG —— MDG on S/4HANA 2023 FPS03 創新匯總

文章目錄 MDG 基于SAP S/4HANA 2023 FPS03的創新BP/C/S&#xff1a;消息控制BP/C/S&#xff1a;手工分配數據控制者MDG-F&#xff1a;使用S/4擴展數據校驗功能生成式AI可用于協助自定義對象的數據變更/同時可總結批量變更的內容 MDG 基于SAP S/4HANA 2023 FPS03的創新 由于從S…

抽獎系統(從0-1)(上)

hu項目的開發流程介紹 1. 項目啟動階段 ? 項?概述&#xff1a;介紹項?的背景、?標和預期成果。 ? 團隊組建&#xff1a;建跨職能團隊&#xff0c;包括產品經理、UI/UX 設計師、開發?員、測試?員等。 ? ??定義&#xff1a;明確團隊中各個??的職責和?作內容。 2. 需…

vim 調整字體

vim: 在vim 面板單擊右鍵&#xff0c;選擇references: terminal :也是單擊右鍵,選擇references:

UniApp 使用 u-loadmore 完整步驟

文章目錄 一、前期準備1. 安裝 uView - UI 二、使用 u-loadmore組件1. 創建頁面2. 編寫頁面代碼模板部分&#xff08;loadmore-demo.vue&#xff09;樣式部分腳本部分 三、要點補充1. u-loadmore 狀態說明2. 數據請求優化3. 性能優化4. 兼容性問題 在 UniApp 開發中&#xff0c…

Libgdx游戲開發系列教程(3)——通過柏林噪音算法地圖隨機地形

在B站刷到了隨機地圖生成的視頻,隨手學習下并做下記錄 注: 本篇使用javafx應用作演示,算是了解這個算法的使用,后續會再出篇libgdx生成地圖的示例 說明 拋開算法實現,首先認知柏林噪音算法 一般我們想要隨機數,會指定個范圍,如0.0-1.0之間任意小數,而柏林算法的結果范圍就是[…