算法訓練之動態規劃(三)


???~~~~~~歡迎光臨知星小度博客空間~~~~~~???

???零星地變得優秀~也能拼湊出星河~???

???我們一起努力成為更好的自己~???

???如果這一篇博客對你有幫助~別忘了點贊分享哦~???

???如果有什么問題可以評論區留言或者私信我哦~???

?????? 個人主頁??????

??????? 接下來這篇博客我們將繼續在題目中使用巧妙的動態規劃思想~準備好了嗎~我們發車去探索奧秘啦~🚗🚗🚗🚗🚗🚗

下降路徑的最小和

下降路徑的最小和

這個題目看起來有點嚇人,別怕,接下來我們一步步按照動態規劃的思想來解決這道問題~

分析:

1、狀態表示

??????? 結合這里的題目要求+經驗:我們這里的狀態表示——dp[i][j]為到達該位置的最小路徑和

2、狀態轉移方程

?????? 我們以離【i】【j】位置最近的狀態分析狀態轉移方程(題目要求最多相隔一列)所以有下面的三種情況:

1、到達該位置,可能是從第【i-1】【j】位置向下一步到達的

2、到達該位置,可能是從第【i-1】【j-1】位置向下再向右一步到達的

3、到達該位置,可能是從第【i-1】【j+1】位置向下再向左一步到達的

?????? 所以到達該位置最小路徑和也就是三種情況的最小值再加上當前位置的數據(注意下標映射關系),所以狀態轉移方程也就是:

??????????????? dp[i][j]=min(min(dp[i-1][j],dp[i-1][j-1]),dp[i-1][j+1]) + nums[i-1][j-1]

3、初始化

??????? 我們可以看到,狀態轉移方程里面有i-1,j-1,j+1當i=0或者j=0或者j=n的時候顯然會出現越界的情況,所以我們需要進行初始化

??????? 結合前面如果不想初始化太麻煩,我們可以多申請一些空間,這里與前面不一樣的是這里是我們這里還有一個j+1,那么我們這里也就可以多申請一行兩列~那么怎么初始化這一行兩列呢?

??????? 我們結合例子來看看:

??????? 我們首先來看看結合我們的邏輯dp[i][j]里面的值在具體的例子中是多少?

????? 我們可以看到第一行就是它本身的值,而第一行是受到我們增加的那一行影響的,所以我們增加的那一行應該全部初始化為0,才不會出錯~接下來看后面的兩行,都是在取上一行三個位置的最小值加上當前位置值得到的,那么旁邊的兩列如果也初始化為0的話,那么邊界找到的最小值就是0了,這并不是數組里面的有效數據~所以為了避免影響,我們也就可以把兩列位置設置成INT_MAX,題目給出數據大小范圍,顯然dp[i][j]是不會超過INT_MAX的,那么我們就可以這樣進行初始化~

??????????????? 第一行初始化為0,剩下的位置初始化為INT_MAX

???????

?

??????? 這種初始化方式還需要注意的是下標的映射關系~

4、填表順序

??????? 我們這里的邏輯是從上面依次推出下面的,所以填表順序是從上向下

5、返回結果

????? 這里返回結果也與我們前面的不一樣,因為它不是一個具體的位置,最小路徑和存在于最后一行,所以我們可以找到dp表最后一行最小值進行返回~

代碼實現:

class Solution 
{
public:int minFallingPathSum(vector<vector<int>>& matrix) {//1、創建dp表int m=matrix.size();int n=matrix[0].size();//多創建一行兩列vector<vector<int>> dp(m+1,vector<int>(n+2,INT_MAX));//最開始就把所有位置初始化為INT_MAX//2、初始化//最開始就把所有位置初始化為INT_MAX了//初始化第一行為0for(int j=0;j<=n+1;j++){dp[0][j]=0;}//3、填表for(int i=1;i<=m;i++){for(int j=1;j<=n;j++){dp[i][j]=min(min(dp[i-1][j-1],dp[i-1][j]),dp[i-1][j+1])+matrix[i-1][j-1];//注意下標映射關系}}//4、返回結果//找到最后一行最小值進行返回int ret=dp[m][1];for(int i=2;i<=n;i++){ret=min(ret,dp[m][i]);}return ret;}
};

順利通過~分析之后也就十分清楚了,我們來看看下一道題目~

最小路徑和

最小路徑和

我們同樣可以一步步來分析:

1、狀態表示

??????? 結合這里的題目要求+經驗:我們這里的狀態表示——dp[i][j]為到達該位置的最小總和

2、狀態轉移方程

?????? 我們以離【i】【j】位置最近的狀態分析狀態轉移方程(題目要求只能向下或者向右移動)所以有下面的兩種情況:

1、到達該位置,可能是從第【i-1】【j】位置向下一步到達的

2、到達該位置,可能是從第【i】【j-1】位置向右一步到達的

?????? 所以到達該位置最小總和也就是兩種情況的最小值再加上當前位置的數據(注意下標映射關系),所以狀態轉移方程也就是:

??????????????? dp[i][j]=min(dp[i-1][j],dp[i][j-1]) + nums[i-1][j-1]

3、初始化

??????? 我們可以看到,狀態轉移方程里面有i-1,j-1當i=0或者j=0的時候顯然會出現越界的情況,所以我們需要進行初始化

??????? 結合前面如果不想初始化太麻煩,我們可以多申請一些空間,那么我們這里結合經驗也就可以多申請一行一列~那么怎么初始化這一行一列呢?

??????? 我們結合例子來看看:

??????? 我們首先來看看結合我們的邏輯dp[i][j]里面的值在具體的例子中是多少?

????? 我們可以看到除了左上角的數就是它本身的值,其他的值都發生了變化,而左上角的數是受到它上面的位置和左邊的位置影響的,結合狀態轉移方程? dp[i][j]=min(dp[i-1][j],dp[i][j-1]) + nums[i-1][j-1],所以它上面的位置和左邊的位置應該初始化為0,才不會出錯~接下來看剩下的位置,每一個位置都是在取當前位置上面的位置和左邊的位置的最小值加上當前位置值得到的,那么如果也初始化為0的話,那么邊界找到的最小值就是0了,這并不是數組里面的有效數據~所以為了避免影響,我們也就可以把剩下的設置成INT_MAX,題目給出數據大小范圍,顯然dp[i][j]是不會超過INT_MAX的,那么我們就可以這樣進行初始化~

?????? dp[1][0]=dp[0][1]=0,剩下的位置初始化為INT_MAX

?

??????? 這種初始化方式還需要注意的是下標的映射關系~

4、填表順序

??????? 我們這里的邏輯是從上面依次推出下面的,所以填表順序是從上向下

5、返回結果

???? 右下角的位置就是我們想要的結果,直接返回dp[m][n]就可以了

有了前面題目的鋪墊,相信這道題目就手到擒來了~

代碼實現:

class Solution 
{
public:int minPathSum(vector<vector<int>>& grid) {//1、創建dp表int m=grid.size();int n=grid[0].size();//dp表最開始全部初始化為INT_MAXvector<vector<int>> dp(m+1,vector<int>(n+1,INT_MAX));//2、初始化dp[0][1]=dp[1][0]=0;//3、填表for(int i=1;i<=m;i++){for(int j=1;j<=n;j++){dp[i][j]=min(dp[i-1][j],dp[i][j-1])+grid[i-1][j-1];//注意下標映射關系}}//4、返回結果return dp[m][n];}
};

順利通過~

地下城游戲

地下城游戲

一看這題目就有點嚇人,我們同樣按照我們之前的步驟來進行分析:

1、狀態表示

??????? 結合這里的題目要求+經驗:狀態表示一般有兩種方式:

1、以某一個位置為結尾分析

??????? 我們這里來看看如果我們以【i】【j】位置為結尾來分析的話,認為dp【i】【j】表示的是到該位置的最低健康點數,那么我們可以發現dp【i】【j】不僅僅受到前面位置的影響,還會受到后面位置的影響,這樣就會十分麻煩,所以我們換一種方式~

2、以某一個位置為起點分析

??????? 我們這里來看看如果我們以【i】【j】位置為起點來分析的話,認為dp【i】【j】表示的是從該位置開始到達指定位置的最低健康點數,那么dp【i】【j】只受到后面位置的影響,這樣就更加方便~

2、狀態轉移方程

?????? 我們以離【i】【j】位置最近的狀態分析狀態轉移方程(題目要求只能向下或者向右移動)所以有下面的兩種情況:

1、以該位置為起點,可能是向下一步到達第【i+1】【j】位置

2、以該位置為起點,可能是向右一步到達第【i】【j+1】位置

?????? 所以dp【i】【j】也就是以該位置為起點,兩種情況的最小值再減去當前位置的數據(這里增加不需要注意下標映射關系),所以狀態轉移方程也就是:

??????????????? dp[i][j]=min(dp[i+1][j],dp[i][j+1]) - nums[i][j]

????????這樣處理之后,還有一種情況就是dp[i][j]是負數了,也就是nums[i][j]很大,那么該位置的最小健康點數只需要是1經過加上nums[i][j]就可以了,所以還需要處理為負數的情況~

??????? dp[i][j]=max(1,dp[i][j])

3、初始化

??????? 我們可以看到,狀態轉移方程里面有i+1,j+1當i=m-1或者j=n-1的時候顯然會出現越界的情況,所以我們需要進行初始化

??????? 結合前面如果不想初始化太麻煩,我們可以多申請一些空間,那么我們這里結合經驗也就可以多申請一行一列~與前面不同的是這里是以【i】【j】位置為起點來分析,所以加的那一行一列在后面,那么怎么初始化這一行一列呢?

??????? 我們結合例子來看看:

??????? 我們首先來看看結合我們的邏輯dp[i][j]里面的值在具體的例子中是多少?

????? 我們可以看到除了右下角的數到達右邊或者下邊那一個位置至少還應該剩下1的健康點數,不能剛好到了就死亡了,所以dp【m-1】【n】=dp【m】【n-1】=1,接下來看剩下的位置,每一個位置都是在取當前位置下面的位置和右邊的位置的最小值加上當前位置值得到的,那么如果也初始化為1的話,那么邊界找到的最小值就是錯誤的~所以為了避免影響,我們也就可以把剩下的設置成INT_MAX,題目給出數據大小范圍,顯然dp[i][j]是不會超過INT_MAX的,那么我們就可以這樣進行初始化~

?????? dp[m-1][n]=dp[m][n-1]=1,剩下的位置初始化為INT_MAX

?

??????? 這種初始化方式還不需要注意下標的映射關系了~因為位置與數組一一對應的~

4、填表順序

??????? 我們這里的邏輯是從下面/右邊依次推出上面/左邊的,所以填表順序是從下向上,從右向左

5、返回結果

???? 左上角的位置就是我們想要的結果,直接返回dp[0][0]就可以了

代碼實現:

class Solution 
{
public:int calculateMinimumHP(vector<vector<int>>& d) {//1、創建dp表int m=d.size();int n=d[0].size();//最開始全部初始化為INT_MAXvector<vector<int>> dp(m+1,vector<int>(n+1,INT_MAX));//2、初始化dp[m-1][n]=dp[m][n-1]=1;//3、填表//注意填表順序for(int i=m-1;i>=0;i--){for(int j=n-1;j>=0;j--){dp[i][j]=min(dp[i+1][j],dp[i][j+1])-d[i][j];//處理為負的情況dp[i][j]=max(1,dp[i][j]);}}//4、返回結果return dp[0][0];}
};

順利通過~


???本篇博客內容結束,期待與各位優秀程序員交流,有什么問題請私信???

???如果這一篇博客對你有幫助~別忘了點贊分享哦~???

??????個人主頁??????


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

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

相關文章

$_GET變量

$_GET 是一個超級全局變量&#xff0c;在 PHP 中用于收集通過 URL 查詢字符串傳遞的參數。它是一個關聯數組&#xff0c;包含了所有通過 HTTP GET 方法發送到當前腳本的變量。 預定義的 $_GET 變量用于收集來自 method"get" 的表單中的值。 從帶有 GET 方法的表單發…

jQuery多庫共存

在現代Web開發中&#xff0c;項目往往需要集成多種JavaScript庫或框架來滿足不同的功能需求。然而&#xff0c;當多個庫同時使用時&#xff0c;可能會出現命名沖突、功能覆蓋等問題。幸運的是&#xff0c;jQuery提供了一些機制來確保其可以與其他庫和諧共存。本文將探討如何實現…

MySQL 中的聚簇索引和非聚簇索引有什么區別?

MySQL 中的聚簇索引和非聚簇索引有什么區別&#xff1f; 1. 從不同存儲引擎去考慮 在MySIAM存儲引擎中&#xff0c;索引和數據是分開存儲的&#xff0c;包括主鍵索引在內的所有索引都是“非聚簇”的&#xff0c;每個索引的葉子節點存儲的是數據記錄的物理地址&#xff08;指針…

Java從入門到“放棄”(精通)之旅——啟航①

&#x1f31f;Java從入門到“放棄 ”精通之旅&#x1f680; 今天我將要帶大家一起探索神奇的Java世界&#xff01;希望能幫助到同樣初學Java的你~ (??????)?? &#x1f525; Java是什么&#xff1f;為什么這么火&#xff1f; Java不僅僅是一門編程語言&#xff0c;更…

三相電為什么沒零線也能通電

要理解三相電為什么沒零線也能通電&#xff0c;就要從發電的原理說起 1、弧形磁鐵中加入電樞&#xff0c;旋轉切割磁感線會產生電流 隨著電樞旋轉的角度變化&#xff0c;電樞垂直切割磁感線 電樞垂直切割磁感線&#xff0c;此時會產生最大電壓 當轉到與磁感線平行時&#xf…

文件上傳做題記錄

1&#xff0c;[SWPUCTF 2021 新生賽]easyupload2.0 直接上傳php 再試一下phtml 用蟻劍連發現連不上 那就只要命令執行了 2&#xff0c;[SWPUCTF 2021 新生賽]easyupload1.0 當然&#xff0c;直接上傳一個php是不行的 phtml也不行&#xff0c;看下是不是前端驗證&#xff0c;…

【Pandas】pandas DataFrame head

Pandas2.2 DataFrame Indexing, iteration 方法描述DataFrame.head([n])用于返回 DataFrame 的前幾行 pandas.DataFrame.head pandas.DataFrame.head 是一個方法&#xff0c;用于返回 DataFrame 的前幾行。這個方法非常有用&#xff0c;特別是在需要快速查看 DataFrame 的前…

日語學習-日語知識點小記-構建基礎-JLPT-N4階段(1):承上啟下,繼續上路

日語學習-日語知識點小記-構建基礎-JLPT-N4階段(1):承上啟下,繼續上路 1、前言(1)情況說明(2)工程師的信仰2、知識點(1)普通形(ふつうけい)と思います(2)辭書形ことができます(3)Vたことがあります。(4)Vた とき & Vる とき3、單詞(1)日語單詞(2…

碼率自適應(ABR)相關論文閱讀簡報

標題&#xff1a;Quality Enhanced Multimedia Content Delivery for Mobile Cloud with Deep Reinforcement Learning 作者&#xff1a;Muhammad Saleem , Yasir Saleem, H. M. Shahzad Asif, and M. Saleem Mian 單位: 巴基斯坦拉合爾54890工程技術大學計算機科學與工程系 …

匯編語言:指令詳解

零、前置知識 1、數據類型修飾符 名稱解釋byte一個字節&#xff0c;8bitword單字&#xff0c;占2個字節&#xff0c;16bitdword雙字&#xff0c;占4個字節&#xff0c;32bitqword四字&#xff0c;占8個字節&#xff0c;64bit 2、關鍵詞解釋 ptr&#xff1a;它代表 pointer&a…

藍橋杯c ++筆記(含算法 貪心+動態規劃+dp+進制轉化+便利等)

藍橋杯 #include <iostream> #include <vector> #include <algorithm> #include <string> using namespace std; //常使用的頭文件動態規劃 小藍在黑板上連續寫下從 11 到 20232023 之間所有的整數&#xff0c;得到了一個數字序列&#xff1a; S12345…

【C++算法】54.鏈表_合并 K 個升序鏈表

文章目錄 題目鏈接&#xff1a;題目描述&#xff1a;解法C 算法代碼&#xff1a; 題目鏈接&#xff1a; 23. 合并 K 個升序鏈表 題目描述&#xff1a; 解法 解法一&#xff1a;暴力解法 每個鏈表的平均長度為n&#xff0c;有k個鏈表&#xff0c;時間復雜度O(nk^2) 合并兩個有序…

Java中的注解技術講解

Java中的注解&#xff08;Annotation&#xff09;是一種在代碼中嵌入元數據的機制&#xff0c;不直接參與業務邏輯&#xff0c;而是為編譯器、開發工具以及運行時提供額外的信息和指導。下面我們將由淺入深地講解Java注解的概念、實現原理、各種應用場景&#xff0c;并通過代碼…

京東與喜茶關系破裂:切斷所有合作 禁止進入辦公場所

快科技4月10日消息&#xff0c;據報道&#xff0c;京東集團近日被曝出內部下發全員禁令&#xff0c;全面封殺喜茶產品進入辦公區域。 據知情人士透露&#xff0c;京東人力行政部門發布的通知明確規定&#xff1a;全國各職場禁止與喜茶品牌開展任何形式的合作&#xff1b;員工不…

+++++背到厭倦。持續更新

Spring IoC 的工作流程: 讀取 BeanDefinition: Spring 容器啟動時&#xff0c;會讀取 Bean 的配置信息 (例如 XML 配置文件、注解或 Java 代碼)&#xff0c;并將這些配置信息轉換為 BeanDefinition 對象。創建 Bean 實例: 根據 BeanDefinition 中的信息&#xff0c;Spring 容器…

如何在Git歷史中抹掉中文信息并翻譯成英文

如何在Git歷史中抹掉中文信息并翻譯成英文 在軟件開發和版本控制領域&#xff0c;維護一個清晰、一致的代碼歷史記錄是至關重要的。然而&#xff0c;有時我們可能會遇到需要修改歷史提交的情況&#xff0c;比如刪除敏感信息或修正錯誤。本文將詳細探討如何在Git歷史中抹掉中文…

21 天 Python 計劃:MySQL中DML與權限管理

文章目錄 前言一、介紹二、MySQL數據操作&#xff1a;DML2.1 插入數據&#xff08;INSERT&#xff09;2.1.1 插入完整數據&#xff08;順序插入&#xff09;2.1.2 指定字段插入數據2.1.3 插入多條記錄2.1.4 插入查詢結果 2.2 更新數據&#xff08;UPDATE&#xff09;2.3 刪除數…

微信小程序 -- 原生封裝table

文章目錄 table.wxmltable.wxss注意 table.js注意 結果數據結構 最近菜鳥做微信小程序的一個查詢功能&#xff0c;需要展示excel里面的數據&#xff0c;但是菜鳥找了一圈&#xff0c;也沒發現什么組件庫有table&#xff0c;畢竟手機端好像確實不太適合做table&#xff01; 菜鳥…

LangChain-輸出解析器 (Output Parsers)

輸出解析器是LangChain的重要組件&#xff0c;用于將語言模型的原始文本輸出轉換為結構化數據。本文檔詳細介紹了輸出解析器的類型、功能和最佳實踐。 概述 語言模型通常輸出自然語言文本&#xff0c;但在應用開發中&#xff0c;我們經常需要將這些文本轉換為結構化的數據格式…

【安全】加密算法原理與實戰

為了理解SSL/TLS原理&#xff0c;大家需要掌握一些加密算法的基礎知識。當然&#xff0c;這不是為了讓大家成為密碼學專家&#xff0c;所以只需對基礎的加密算法有一些了解即可。基礎的加密算法主要有哈希&#xff08;Hash&#xff0c;或稱為散列&#xff09;?、對稱加密(Symm…