[動態規劃及遞歸記憶搜索法]1.鋼條切割問題

摘要

本系列從6道經典的動態規劃題入手,去理解動態規劃的基本思路和想法,以及動態規劃和遞歸記憶搜索法存在的某些聯系,對于每道題目,我們將用兩種方法去實現,這里講解第一道題目,作個開頭。

前言

我們知道,大部分的動態規劃題目可以利用遞歸加記憶搜索法去完成,這兩者的程序速度方面并沒有較大的區別。

動態規劃(DP)和記憶化搜索(也稱為遞歸記憶)是兩種解決復雜問題的常用技術,它們都利用了子問題的解來構建原問題的解。

動態規劃是一種自底向上的方法,它首先解決子問題,然后基于子問題的解來解決更大的問題。動態規劃通常使用一個表格來存儲子問題的解,這樣在需要時就可以直接查找,而不需要重新計算。因此,動態規劃通常用于最優化問題,如最短路徑問題、最大子序列和問題等。

記憶化搜索是一種自頂向下的方法,它從原問題開始,然后遞歸地解決子問題。當一個子問題被解決時,它的解將被存儲起來,以便在后續需要時使用。記憶化搜索在處理具有重疊子問題的遞歸問題時非常有效。

在速度上,動態規劃和記憶化搜索通常具有相似的時間復雜度,因為它們都利用了子問題的解來避免重復計算。然而,具體的速度可能會根據問題的特性以及實現的細節而有所不同。例如,對于某些問題,動態規劃可能需要解決所有的子問題,而記憶化搜索則只需要解決那些實際上被用到的子問題。因此,對于這些問題,記憶化搜索可能會比動態規劃更快。然而,對于其他問題,動態規劃可能會有更好的性能,因為它可以更有效地利用存儲的子問題解。

總的來說,選擇使用動態規劃還是記憶化搜索通常取決于問題的特性以及個人的編程風格和經驗。

題目

1.鋼條切割問題

題目描述

Serling公司購買長鋼條,將其切割為短鋼條出售。切割工序本身沒有成本支出。公司管理層希望知道最佳的切割方案。假定我們知道Serling公司出售一段長為i英寸的鋼條的價格為pi(i=1,2,…,單位為美元)。鋼條的長度均為整英寸。
給定一段長度為n英寸的鋼條和一個價格表pi(i=1,2,…n),求切割鋼條方案,使得銷售收益rn最大。

關于輸入

第一行:n,表示購買的長鋼條的長度。
接下來一行包含 n 個數字,第 i 個數字出售長為 i 的鋼條的價格,即 pi。
其中 0 < n <= 3000,0 < pi <= 10000。

關于輸出

輸出僅一行,為最大的銷售收益值 rn。

例子輸入
7
1 5 8 9 10 17 17
例子輸出
18
提示信息

注意,如果長度為n英寸的鋼條的價格pn足夠大,最優解可能就是完全不需要切割。

解題思路

首先,我們從第一道題目先開始介紹一下動態規劃的基本解題策略和方法:

動態規劃(Dynamic Programming,簡稱 DP)是一種解決復雜問題的策略,主要用于優化問題,如求最大值、最小值或者計數問題等。下面是動態規劃的基本思路和解決策略:

1. **確定狀態**:在動態規劃中,狀態通常表示為一個或多個變量的組合,這些變量能夠完全描述一個問題。例如,在背包問題中,狀態可能是當前的重量和價值。

2. **確定狀態轉移方程**:狀態轉移方程是描述如何從一個狀態到另一個狀態的規則。在大多數情況下,這個規則是基于問題的特性和邏輯來確定的。例如,在最長公共子序列問題中,如果兩個字符相等,那么最長公共子序列的長度就是前一個狀態的長度加一;否則,最長公共子序列的長度就是前兩個狀態中較大的那個。

3. **確定邊界條件**:邊界條件描述了當問題降到最小規模時的解。例如,在斐波那契數列問題中,邊界條件是第一項和第二項分別為1。

4. **計算并存儲狀態**:在動態規劃中,一般會使用一個表格(一維、二維或者更高維度)來存儲所有的狀態。計算順序通常是從邊界條件開始,根據狀態轉移方程逐步計算出所有的狀態。

5. **根據存儲的狀態得到最終結果**:在計算出所有的狀態后,可以根據題目要求從存儲的狀態中得到最終的結果。

動態規劃的關鍵是理解狀態和狀態轉移方程的概念。一旦理解了這兩個概念,就可以應用動態規劃來解決各種各樣的問題。在實際應用中,可能需要花費一些時間和思考來確定正確的狀態和狀態轉移方程。

我們試著帶著這些想法去審視本題,題目給出了兩個信息:鋼條的總長度和每一段特定長度的鋼條的價錢。如果我們選用一個dp數組,我們先考慮一下自己需要幾維的dp數組,入門階段來說,一般我們考慮一維或者二維就可以了,這取決于我們給的狀態能否完全描述一個問題(比如我上篇寫的旅行商問題,由于狀態過于復雜,我們采用了一種二進制壓縮狀態的方法作為dp數組的一個變量,用當前所在城市作為dp數組的第二個變量,以此來構建整個問題)。

對于這個鋼條切割的問題,其實根據題目給的信息,又由于鋼條是連續的,長度的價格也是連續的,所以一個變量即可比較好的描述我們的問題的,我們這樣定義,dp[n]表示,切割n長度的鋼條可以獲得的最大收益。

接下來,讓我們先去想想轉移方程,要切割n長度的鋼條,我們是不是可以選擇先切割一長度下來,再切割[n-1]長度的鋼條?或者說,先切割k長度的鋼條,再切割[n-k]長度鋼條?其中k=1,2,3.....,n。這樣,為求出最大的價錢,我們可以利用以下的動態規劃轉移方程:

dp[n]=max{dp[n-1]+p[1],dp[n-2]+p[2],......,dp[0]+p[n]}。

再來定義一下邊界條件,顯然,dp[0]=0,切割0長度的鋼條自然一分錢沒有。

這樣的轉移方程合理嗎?能推導出最終的答案嗎?如果能,又怎么用程序去實現?

首先,為了完成這個過程,一個循環是不太夠的,我們需要用兩層循環,外層循環控制一個變量k,表示先切割k長度的鋼條下來,因為對于每個長度的鋼條我們需要比較的次數是不一樣的,第二層循環用一個變量j,表示當前對j長度的鋼條操作,當j為[1]時,我們只需要比較一次,就是dp[1],當j為2時,我們會比較兩次,dp[2-1]+p[1]?和dp[2-2]+p[2],當j=3時,我們會比較三次,dp[3-1]+p[1] dp[3-2]+p[2],dp[3-3]+p[0],以此類推,而且由于我們是從低往高處推導的,所以,對于n=n-1時候,命題成立,我們可以推出對于n時命題也成立,而且經過我們的驗證,n=1和n=2時都滿足題意,故,這樣的算法是可行的。

問題一dp代碼展示
#include <iostream>
using namespace std;
#define INF 1e9int p[3005];
int dp[3005];int main() {int n; cin>>n;for(int i=1;i<=n;i++){cin>>p[i];}for(int i=1;i<=n;i++){dp[i]=-INF;}dp[0]=0;for(int k=1;k<=n;k++)for(int j=k;j<=n;j++){dp[j]=max(dp[j],dp[j-k]+p[k]);}cout<<dp[n]<<endl;return 0;
}
這里再附上使用記憶搜索法加遞歸函數的方法的代碼:

定義f(n)表示切割n長度鋼條能得到的最大收益

#include <iostream>
using namespace std;int p[3005];
int dp[3005];int f(int n){if(n<=0){return 0;}if(dp[n]!=-1){return dp[n];}for(int k=1;k<=n;k++){dp[n]=max(dp[n],f(n-k)+p[k]);}return dp[n];
}int main() {int n; cin>>n;for(int i=1;i<=n;i++){cin>>p[i];}for(int i=1;i<=n;i++){dp[i]=-1;}cout<<f(n)<<endl;return 0;
}

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

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

相關文章

elasticsearch 內網下如何以離線的方式上傳任意的huggingFace上的NLP模型(國內避坑指南)

es自2020年的8.x版本以來&#xff0c;就提供了機器學習的能力。我們可以使用es官方提供的工具eland&#xff0c;將hugging face上的NLP模型&#xff0c;上傳到es集群中。利用es的機器學習模塊&#xff0c;來運維部署管理模型。配合es的管道處理&#xff0c;來更加便捷的處理數據…

吳恩達《機器學習》12-1:優化目標

在機器學習的旅程中&#xff0c;我們已經接觸了多種學習算法。在監督學習中&#xff0c;選擇使用算法 A 還是算法 B 的重要性逐漸減弱&#xff0c;而更關鍵的是如何在應用這些算法時優化目標。這包括設計特征、選擇正則化參數等因素&#xff0c;這些在不同水平的實踐者之間可能…

UG NX二次開發(C#)-求曲線在某一點處的法矢和切矢

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 文章目錄 1、前言2、在UG NX中創建一個曲線3、直接放代碼4、測試案例1、前言 最近確實有點忙了,好久沒更新博客了。今天恰好有時間,就更新下,還請家人們見諒。 今天我們講一下如何獲取一條曲線上某一條曲…

注意力機制的快速學習

注意力機制的快速學習 注意力機制 將焦點聚焦在比較重要的事物上 我&#xff08;查詢對象Q&#xff09;&#xff0c;這張圖&#xff08;被查詢對象V&#xff09; 我看一張圖&#xff0c;第一眼&#xff0c;就會判斷那些東西對我而言比較重要&#xff0c;那些對于我不重要&…

Pytorch從零開始實戰12

Pytorch從零開始實戰——DenseNet算法實戰 本系列來源于365天深度學習訓練營 原作者K同學 文章目錄 Pytorch從零開始實戰——DenseNet算法實戰環境準備數據集模型選擇開始訓練可視化總結 環境準備 本文基于Jupyter notebook&#xff0c;使用Python3.8&#xff0c;Pytorch2.…

Elasticsearch、Logstash、Kibana(ELK)環境搭建

下面是 Elasticsearch、Logstash、Kibana&#xff08;ELK&#xff09;環境搭建的具體操作步驟&#xff1a; 安裝 Java ELK 是基于 Java 編寫的&#xff0c;因此需要先安裝 Java。建議安裝 Java 8 或以上版本。 下載并安裝 Elasticsearch Elasticsearch 是一個基于 Lucene 的…

DevEco Studio 運行項目有時會自動出現.js和.map文件

運行的時候報錯了&#xff0c;發現多了.js和.map&#xff0c;而且還不是一個&#xff0c;很多個。 通過查詢&#xff0c;好像是之前已知問題了&#xff0c;給的建議是手動刪除(一個一個刪)&#xff0c;而且有的評論還說&#xff0c;一周出現了3次&#xff0c;太可怕了。 搜的過…

【網絡編程】-- 02 端口、通信協議

網絡編程 3 端口 端口表示計算機上的一個程序的進程 不同的進程有不同的端口號&#xff01;用來區分不同的軟件進程 被規定總共0~65535 TCP,UDP&#xff1a;65535 * 2 在同一協議下&#xff0c;端口號不可以沖突占用 端口分類&#xff1a; 公有端口&#xff1a;0~1023 HT…

【android開發-23】android中WebView的用法詳解

1&#xff0c;WabView的用法 在Android中&#xff0c;WebView是一個非常重要的組件&#xff0c;它允許我們在Android應用中嵌入網頁&#xff0c;展示HTML內容。WebView是Android SDK中提供的標準組件&#xff0c;使用它我們可以很方便地將web頁面直接嵌入到Android應用中。Web…

亞信安慧AntDB數據庫中級培訓ACP上線,中國移動總部首批客戶認證通過

近日&#xff0c;亞信安慧AntDB數據庫ACP&#xff08;AntDB Certified Professional&#xff09;中級培訓課程于官網上線。在中國移動總部客戶運維團隊、現場項目部伙伴和AntDB數據庫成員的協同組織下&#xff0c;首批中級認證學員順利完成相關課程的培訓&#xff0c;并獲得Ant…

自然語言處理22-基于本地知識庫的快速問答系統,利用大模型的中文訓練集為知識庫

大家好,我是微學AI,今天給大家介紹一下自然語言處理22-基于本地知識庫的快速問答系統,利用大模型的中文訓練集為知識庫。我們的快速問答系統是基于本地知識庫和大模型的最新技術,它利用了經過訓練的中文大模型,該模型使用了包括alpaca_gpt4_data的開源數據集。 一、本地…

C //例10.3 從鍵盤讀入若干個字符串,對它們按字母大小的順序排序,然后把排好序的字符串送到磁盤文件中保存。

C程序設計 &#xff08;第四版&#xff09; 譚浩強 例10.3 例10.3 從鍵盤讀入若干個字符串&#xff0c;對它們按字母大小的順序排序&#xff0c;然后把排好序的字符串送到磁盤文件中保存。 IDE工具&#xff1a;VS2010 Note: 使用不同的IDE工具可能有部分差異。 代碼塊 方法…

2023_Spark_實驗二十五:SparkStreaming讀取Kafka數據源:使用Direct方式

SparkStreaming讀取Kafka數據源&#xff1a;使用Direct方式 一、前提工作 安裝了zookeeper 安裝了Kafka 實驗環境&#xff1a;kafka zookeeper spark 實驗流程 二、實驗內容 實驗要求&#xff1a;實現的從kafka讀取實現wordcount程序 啟動zookeeper zk.sh start# zk.sh…

生成元(Digit Generator, ACM/ICPC Seoul 2005, UVa1583)

如果x加上x的各個數字之和得到y&#xff0c;就說x是y的生成元。 給出n&#xff08;1≤n≤100000&#xff09;&#xff0c;求最小生成元。 無解輸出0。 例如&#xff0c;n216&#xff0c;121&#xff0c;2005時的解分別為198&#xff0c;0&#xff0c;1979。 我的思路很簡單&am…

element-UI中el-scrollbar的使用

在elment-ui中有這么一個滾動條&#xff0c;當鼠標over到內容部分才會顯示&#xff0c;移開鼠標之后滾動條就會隱藏起來&#xff0c;相較于原生的滾動條比較美觀。 <el-scrollbar> //將滾動條的內部的內容放在里面即可 </el-scrollbar> 在使用過程中&#xff…

SNMP陷阱監控工具

SNMP&#xff08;簡單網絡管理協議&#xff09;是網絡管理的一個重要方面&#xff0c;其中網絡設備&#xff08;包括路由器、交換機和服務器&#xff09;在滿足預定義條件時將SNMP陷阱作為異步通知發送到中央管理系統。簡而言之&#xff0c;每當發生關鍵服務器不可用或硬件高溫…

microblaze仿真

verdivcs (1) vlogan/vcs增加編譯選項 -debug_accessall -kdb -lca (2) 在 simulation 選項中加入下面三個選項 -guiverdi UVM_VERDI_TRACE"UVM_AWARERALHIERCOMPWAVE" UVM_TR_RECORD 這里 -guiverdi是啟動verdi 和vcs聯合仿真。UVM_VERDI_TRACE 這里是記錄 U…

第四十二篇,MATLAB on Linux

最近在Ubuntu上安裝了一把MATLAB&#xff0c;以下操作親測有效。 一、版本 Linux&#xff1a;Ubuntu 18.04 MATLAB&#xff1a;R2021a Linux版&#xff0c;910 MATLAB下載鏈接&#xff1a;提取碼MUYU&#xff0c;感謝大佬無私奉獻&#xff01; 二、安裝 詳細的安裝步驟不…

linux高級篇基礎理論七(Tomcat)

??作者&#xff1a;小劉在C站 ??個人主頁&#xff1a; 小劉主頁 ??不能因為人生的道路坎坷,就使自己的身軀變得彎曲;不能因為生活的歷程漫長,就使求索的 腳步遲緩。 ??學習兩年總結出的運維經驗&#xff0c;以及思科模擬器全套網絡實驗教程。專欄&#xff1a;云計算技…

算法題,文本左右對齊

/*** 給定一個單詞數組 words 和一個長度 maxWidth &#xff0c;重新排版單詞&#xff0c;使其成為每行恰好有 maxWidth 個字符&#xff0c;且左右兩端對齊的文本。** 你應該使用 “貪心算法” 來放置給定的單詞&#xff1b;也就是說&#xff0c;盡可能多地往每行中放置單詞。必…