動態規劃之爬樓梯模型

文章目錄

  • 爬樓梯模型
    • LeetCode 746. 使用最小花費爬樓梯
      • 思路
      • Golang 代碼
    • LeetCode 377. 組合總和 Ⅳ
      • 思路
      • Golang 代碼
    • LeetCode 2466. 統計構造好字符串的方案數
      • 思路
      • Golang 代碼
    • LeetCode 2266. 統計打字方案數
      • 思路
      • Golang 代碼

爬樓梯模型

在這里插入圖片描述
爬樓梯模型是動態規劃當中的一個經典模型,可以抽象為:在當前這一步,你有若干個可選的操作,比如前進一步或前進兩步,試問最少需要多少步能夠到達終點。一個可能的變形是每一步具有固定的代價,試問到達終點的最小代價是多少。

最經典的爬樓梯問題就是初始時你處于第一層(第零級臺階),每次可以爬一個臺階或兩個臺階,請問到達第 n 級臺階最少需要多少步。

依據這個最基本的爬樓梯模型,派生出了許多變體,參考靈茶山艾府整理的文檔:分享丨【算法題單】動態規劃(入門/背包/劃分/狀態機/區間/狀壓/數位/樹形/優化),將這些題目的思路在此進行收錄。

LeetCode 746. 使用最小花費爬樓梯

思路

可以看作是爬樓梯問題最簡單的變體,在爬樓梯的過程中為每一步引入了代價,試問爬到終點最小的代價是多少。

使用 dp 數組記錄的狀態就是爬到當前這一級臺階的最小代價,由此可以推出狀態轉移方程:dp[i] = min(dp[i - 1] + cost[i - 1] + dp[i - 2] + cost[i - 2]),根據狀態轉移方程直接寫代碼即可。

Golang 代碼

func minCostClimbingStairs(cost []int) int {n := len(cost)if n < 3 {return min(cost[0], cost[1])}dp := make([]int, n + 1)for i := 2; i <= n; i ++ {dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2])}return dp[n]
}

LeetCode 377. 組合總和 Ⅳ

思路

可以將最終的 target 視為要攀爬的目標樓梯數,將 nums 數組當中的數字視為一次行動可以攀爬的樓梯數,這道題目可以抽象為一個爬樓梯問題。

具體來說,使用 dp 數組記錄爬到某一層需要多少次行動,初始化 dp[0] = 1,作為動態規劃的邊界狀態。狀態轉移方程可以寫為: d p [ i ] = ∑ j = 0 n ? 1 d p [ i ? n u m s [ j ] dp[i] = \sum^{n-1}_{j=0}dp[i-nums[j] dp[i]=j=0n?1?dp[i?nums[j],前提是 i ≥ n u m s [ j ] i\geq nums[j] inums[j]

Golang 代碼

func combinationSum4(nums []int, target int) int {n := len(nums)dp := make([]int, target + 1)dp[0] = 1for i := 1; i <= target; i ++ {for j := 0; j < n; j ++ {if i >= nums[j] {dp[i] += dp[i - nums[j]]}}}return dp[target]
}

LeetCode 2466. 統計構造好字符串的方案數

思路

從這一題開始,稍有難度。其實這道題本質上也是一個爬樓梯問題,zero 和 one 指的就是一次行動可以攀爬的樓梯數,只要爬上的臺階大于等于 low,就可以記錄答案。

使用 dp 數組記錄的是構造長度為 i 的字符串的方案數,只要 i 大于等于 low,那么dp[i]就是答案的一部分。

可以得到初步的狀態轉移方程:

dp[i]=dp[i-one]+dp[i-zero]

還需要考慮由于答案可能過大的取模情況,詳見代碼。

Golang 代碼

func countGoodStrings(low int, high int, zero int, one int) int {dp := make([]int, high + 1)dp[0] = 1const MOD int = 1e9 + 7ans := 0for i := 1; i <= high; i ++ {if i >= zero {dp[i] = dp[i - zero] % MOD}if i >= one {dp[i] = (dp[i] + dp[i - one]) % MOD}if i >= low {ans = (ans + dp[i]) % MOD}}return ans
}

LeetCode 2266. 統計打字方案數

思路

這應該是靈神題單里最難的一道題,實際上也是一道爬樓梯問題。具體來說,根據不同數字的重復數,每一個號碼能夠構造出的字母方案可以被視為一個爬樓梯問題。比如對于數字 3,它對應的字符是“def”,如果按 1 次 3,那么只能構造出 d,如果按 2 次,可以構造出 dd 或 e,按 3 次,可以構造出 ddd/de/f/ed,使用 dp 來記錄重復號碼可能構造出的字符數,對于 7 和 9 之外的號碼,狀態轉移方程是dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3],而對于 7 和 9 這兩個有四個字符的號碼,狀態轉移方程是dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3] + dp[i - 4]。預先將這兩個 dp 數組處理出來即可。

每一次對一段重復的號碼進行統計(最小的重復數是 1,也就是只按下一次這個按鍵),之后如果號碼不再重復,就統計答案,這里要用到乘法原理,因為不同號碼構造出的可能字符數的情況是互斥的。

Golang 代碼

func countTexts(pressedKeys string) int {const MOD int = 1e9 + 7n := len(pressedKeys)dp3 := []int{1, 1, 2, 4}dp4 := []int{1, 1, 2, 4}for i := 4; i <= n; i ++ {dp3 = append(dp3, (dp3[i - 1] + dp3[i - 2] + dp3[i - 3]) % MOD)dp4 = append(dp4, (dp4[i - 1] + dp4[i - 2] + dp4[i - 3] + dp4[i - 4]) % MOD)}ans, cnt := 1, 1    // ans 記錄最終的答案, cnt 記錄當前字符的重復數for i := 1; i < n; i ++ {if pressedKeys[i] == pressedKeys[i - 1] {// 當前字符和前一個字符重復, cnt ++cnt ++} else {// 當前字符和前一個字符不重復, 此時要做的就是統計答案// 需要注意的是, 現在統計的是前一個字符的答案, 當前字符要在下一次 pressedKeys[i] != pressedKeys[i - 1] 的時候統計// 這就意味著 i == n - 1 的情況需要在這個 for loop 之后單獨考慮if pressedKeys[i - 1] == '7' || pressedKeys[i - 1] == '9' {ans = ans * dp4[cnt] % MOD} else {ans = ans * dp3[cnt] % MOD}cnt = 1 // 重復的字符數重置為 1}}if pressedKeys[n - 1] == '7' || pressedKeys[n - 1] == '9' {ans = ans * dp4[cnt] % MOD} else {ans = ans * dp3[cnt] % MOD}return ans
}

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

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

相關文章

【每天一個知識點】湖倉一體(Data Lakehouse)

“湖倉一體”&#xff08;Data Lakehouse&#xff09;是一種融合了數據湖&#xff08;Data Lake&#xff09;與數據倉庫&#xff08;Data Warehouse&#xff09;優勢的新型數據架構。它既繼承了數據湖對多類型數據的靈活存儲能力&#xff0c;也具備數據倉庫對結構化數據的高效查…

Linux | mdadm 創建軟 RAID

注&#xff1a;本文為 “Linux mdadm RAID” 相關文章合輯。 略作重排&#xff0c;未整理去重。 如有內容異常&#xff0c;請看原文。 Linux 下用 mdadm 創建軟 RAID 以及避坑 喵??&#xfecc;?? Oct 31, 2023 前言 linux 下組軟 raid 用 mdadm 命令&#xff0c;multi…

Unity自定義shader打包SpriteAtlas圖集問題

Unity打包圖集還是有一些坑的&#xff0c;至于圖集SpriteAtlas是什么請參考我之前寫的文章&#xff1a;【Sprite Atlas】Unity新圖集系統SpriteAtlas超詳細使用教程_spriteatlas 使用-CSDN博客 問題&#xff1a; 今天碰到的問題是&#xff0c;shader繪制的時候&#xff0c;因…

如何用 OceanBase 的 LOAD DATA 旁路導入進行大表遷移

前言 在日常工作中&#xff0c;我們時常會遇到需要將某個大數據量的單表進行遷移的情況。在MySQL中&#xff0c;針對這樣的大表&#xff0c;我們通常會選擇先將原表導出為csv格式&#xff0c;然后利用LOAD DATA語法來導入csv文件&#xff0c;這種方法相較于mysqldump在效率上有…

VR 互動實訓的顯著優勢?

&#xff08;一&#xff09;沉浸式學習&#xff0c;提升培訓效果? 在 VR 互動實訓中&#xff0c;員工不再是被動的知識接受者&#xff0c;而是主動的參與者。以銷售培訓為例&#xff0c;員工戴上 VR 設備&#xff0c;就能置身于逼真的銷售場景中&#xff0c;與虛擬客戶進行面對…

OpenCV 第6課 圖像處理之幾何變換(重映射)

1. 概述 簡單來說,重映射就是把一副圖像內的像素點按照規則映射到到另外一幅圖像內的對應位置上去,形成一張新的圖像。 因為原圖像與目標圖像的像素坐標不是一一對應的。一般情況下,我們通過重映射來表達每個像素的位置(x,y),像這樣: g(x,y)=f(h(x,y)) 在這里g()是目標圖…

Java虛擬機 - 程序計數器和虛擬機棧

運行時數據結構 Java運行時數據區程序計數器為什么需要程序計數器執行流程虛擬機棧虛擬機棧作用虛擬機棧核心結構運行機制 Java運行時數據區 首先介紹Java運行時數據之前&#xff0c;我們要了解&#xff0c;對于計算機來說&#xff0c;內存是非常重要的資源&#xff0c;因為內…

MySQL數據庫——支持遠程IP訪問的設置方法總結

【系列專欄】&#xff1a;博主結合工作實踐輸出的&#xff0c;解決實際問題的專欄&#xff0c;朋友們看過來&#xff01; 《項目案例分享》 《極客DIY開源分享》 《嵌入式通用開發實戰》 《C語言開發基礎總結》 《從0到1學習嵌入式Linux開發》 《QT開發實戰》 《Android開發實…

CSS- 4.6 radiu、shadow、animation動畫

本系列可作為前端學習系列的筆記&#xff0c;代碼的運行環境是在HBuilder中&#xff0c;小編會將代碼復制下來&#xff0c;大家復制下來就可以練習了&#xff0c;方便大家學習。 HTML系列文章 已經收錄在前端專欄&#xff0c;有需要的寶寶們可以點擊前端專欄查看&#xff01; 點…

排序算法之基礎排序:冒泡,選擇,插入排序詳解

排序算法之基礎排序&#xff1a;冒泡、選擇、插入排序詳解 前言一、冒泡排序&#xff08;Bubble Sort&#xff09;1.1 算法原理1.2 代碼實現&#xff08;Python&#xff09;1.3 性能分析 二、選擇排序&#xff08;Selection Sort&#xff09;2.1 算法原理2.2 代碼實現&#xff…

第十節第一部分:常見的API:Math、System、Runtime

Math類介紹及常用方法&#xff08;了解知道即可&#xff09; System類介紹及常用方法&#xff08;了解知道即可&#xff09; Runtime類介紹及常用方法&#xff08;了解知道即可&#xff09; 代碼&#xff1a; 代碼一&#xff1a;Math類 package com.itheima.d14_math;public …

智能體間協作的“巴別塔困境“如何破解?解讀Agent通信4大協議:MCP/ACP/A2A/ANP

AI 智能體的興起觸發了AI應用協作的新領域。這些智能體不再局限于被動的聊天機器人或獨立的系統&#xff0c;它們現在被設計用于推理、計劃和協作ーー跨任務、跨域甚至跨組織。但隨著這一愿景成為現實&#xff0c;一個挑戰很快浮出水面&#xff1a; 智能體如何以一種安全、可伸…

項目進度延誤,如何按時交付?

項目進度延誤可以通過加強計劃管理、優化資源分配、強化團隊溝通、設置關鍵里程碑和風險管理機制等方式來實現按時交付。加強計劃管理、優化資源分配、強化團隊溝通、設置關鍵里程碑、風險管理機制。其中&#xff0c;加強計劃管理尤為關鍵&#xff0c;因為明確而詳細的計劃能提…

詳解ip地址、子網掩碼、網關、廣播地址

1. IP 地址 定義&#xff1a;IP 地址是網絡設備在網絡中的唯一標識&#xff0c;用于標識設備的網絡位置&#xff0c;類似于現實中的門牌號。它分為 IPv4&#xff08;如 192.168.1.5&#xff09;和 IPv6&#xff08;如 240e:305:3685:8100:a00:27ff:fefb:56b8&#xff09;。 示…

為 Windows 和 Ubuntu 中設定代理服務器的詳細方法

有時下載大模型總是下載不出來&#xff0c;要配置代理才行 一、Windows代理設置 ① 系統全局代理設置 打開【設置】→【網絡和Internet】→【代理】。 在【手動設置代理】下&#xff0c;打開開關&#xff0c;輸入&#xff1a; 地址&#xff1a;10.10.10.215 端口&#xff1a;…

鴻蒙OSUniApp 實現的表單驗證與提交功能#三方框架 #Uniapp

UniApp 實現的表單驗證與提交功能 前言 在移動端應用開發中&#xff0c;表單是用戶與應用交互的重要媒介。一個好的表單不僅布局合理、使用方便&#xff0c;還應該具備完善的驗證與提交功能&#xff0c;以確保用戶輸入的數據準確無誤。本文將分享如何在 UniApp 中實現表單驗證…

前端的面試筆記——HTMLJavaScript篇(二)前端頁面性能檢測

前端頁面性能檢測和判定是優化用戶體驗的核心環節&#xff0c;需要結合實驗室數據&#xff08;Lab Data&#xff09;、現場數據&#xff08;Field Data&#xff09;和行業標準綜合評估。以下是主流方法、工具及判定標準的詳細解析&#xff1a; 一、性能檢測的核心維度與指標 …

再來1章linux系列-19 防火墻 iptables 雙網卡主機的內核 firewall-cmd firewalld的高級規則

學習目標&#xff1a; 實驗實驗需求實驗配置內容和分析 &#xff08;每一個設備的每一步操作&#xff09;實驗結果驗證其他 學習內容&#xff1a; 實驗實驗需求實驗配置內容和分析 &#xff08;每一個設備的每一步操作&#xff09;實驗結果驗證其他 1.實驗 2.實驗需求 圖…

LLM-Based Agent綜述及其框架學習(五)

文章目錄 摘要Abstract1. 引言2. 文本輸出3. 工具的使用3.1 理解工具3.2 學會使用工具3.3 制作自給自足的工具3.4 工具可以擴展LLM-Based Agent的行動空間3.5 總結 4. 具身動作5. 學習智能體框架5.1 CrewAI學習進度5.2 LangGraph學習進度5.3 MCP學習進度 參考總結 摘要 本文圍繞…

游戲引擎學習第298天:改進排序鍵 - 第1部分

關于向玩家展示多個房間層所需的兩種 Z 值 我們在前一天基本完成了為渲染系統引入分層 Z 值的工作&#xff0c;但還沒有完全完成所有細節。我們開始引入圖形渲染中的分層概念&#xff0c;即在 Z 軸方向上擁有多個獨立圖層&#xff0c;每個圖層內部再使用一個單獨的 Z 值來實現…