初級演算法-動態規劃
摘要
本篇主要介紹動態規劃解題思路
概括
動態規劃主要是解一些遞迴問題,也就是將遞迴寫成非遞迴方式,因為編輯器無法正確對待遞迴,遞迴方法會導致很多計算結果被重複計算,比如菲波那切數列。
所以動態規劃的解題思路也就是
1. 列出遞迴表示式
2. 將遞迴方法寫成非遞迴方式
比如菲波那切數列
F(n) = F(n-1) + F(n-2)
使用兩個中間變數儲存之前的計算結果,就改寫成了非遞迴方式實現,也就是動態規劃。
常見的題
leetcode 動態規劃題
https://leetcode-cn.com/explore/interview/card/top-interview-questions-easy/23/dynamic-programming/
一. 爬樓梯
假設你正在爬樓梯。需要 n 步你才能到達樓頂。
每次你可以爬 1 或 2 個臺階。你有多少種不同的方法可以爬到樓頂呢?
按照解題方法,寫列出遞迴方程
設定dp[i] 表示走到某個臺階的方法,那麼就有遞迴方程
dp[1] = 1;dp[2] = 2(一次走一步/一次走二步)
dp[3] = dp[1] + dp[2] (從dp[1]中方法中,走2步上來,或者從dp[2]種方法中走1步上來)
dp[n] = dp[n-2] + dp[n-1]
寫成非遞迴方法
public static int climbStairs(int n) {
if(n < 1) {
return 0;
}
if (n == 1) {
return 1;
}
if (n == 2) {
return 2;
}
int dp[] = new int [] {1,2};
int result = dp[0] + dp[1];
for (int i = 3; i <= n; i++) {
result = dp[0] + dp[1];
dp[0] = dp[1];
dp[1] = result;
}
return result;
}
二. 最大子序列
給定一個整數陣列 nums ,找到一個具有最大和的連續子陣列(子陣列最少包含一個元素),返回其最大和。
- 列出遞迴方程
以 nums[-2,1,-3,4,-1,2,1,-5,4] 為例, dp[i]表示遍歷到第i個數時,當前最大連續子陣列和
dp[1] = -2, dp[2] = Math.max(dp[1] + nums[2],nums[2]),因為要求是連續子陣列,所以nums[i]必須接上,
然後再比較歷史最大的的連續子陣列和這次的最大值
程式碼如下
public static int maxSubArray(int[] nums) {
if (nums.length == 0) {
return 0;
}
if (nums.length == 1) {
return nums[0];
}
int result = Math.max(nums[0]+nums[1],nums[1]);
int dp = result;
int max = Math.max(result, nums[0]);
for (int i = 2; i< nums.length; i++) {
result = Math.max(dp+nums[i],nums[i]);
dp = result;
// 如果比歷史的大,就替換
if (result > max) {
max = result;
}
}
return max;
}
三. 打家劫舍
你是一個專業的小偷,計劃偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。
給定一個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額
如 [2,7,9,3,1]
設定dp[i] 是偷i個房屋,所能偷竊到的最高金額,dp[1] = 2, dp[2] = 7, dp[3] = 2+9,Math.max(dp[1] + nums[3], dp[2])
遞迴方程
dp[i] = max(dp[i-2] + nums[i], dp[i-1])
非遞迴方法實現
public static int rob(int[] nums) {
if (nums.length ==0) {
return 0;
}
if (nums.length == 1) {
return nums[0];
}
if (nums.length ==2) {
return Math.max(nums[0],nums[1]);
}
int dp[] = new int[] {nums[0], Math.max(nums[0], nums[1])};
int result=0;
for (int i = 2; i < nums.length; i++) {
result = Math.max(dp[0] + nums[i], dp[1]);
dp[0] = dp[1];
dp[1] = result;
}
return result;
}
相關文章
- 動態規劃初級動態規劃
- 演算法系列-動態規劃(1):初識動態規劃演算法動態規劃
- [leetcode初級演算法]動態規劃總結LeetCode演算法動態規劃
- 動態規劃演算法動態規劃演算法
- 演算法_動態規劃演算法動態規劃
- 演算法-動態規劃演算法動態規劃
- 前端演算法 - 動態規劃前端演算法動態規劃
- 動態規劃演算法(轉)動態規劃演算法
- 【每日演算法】動態規劃四演算法動態規劃
- Python演算法:動態規劃Python演算法動態規劃
- 【動態規劃(一)】動態規劃基礎動態規劃
- 動態規劃中初識狀態壓縮(入門)動態規劃
- 演算法(七):圖解動態規劃演算法圖解動態規劃
- 演算法之動態規劃總結演算法動態規劃
- Java 演算法-最大矩形(動態規劃)Java演算法動態規劃
- 演算法-動態規劃-完全揹包演算法動態規劃
- 動態規劃動態規劃
- 演算法---貪心演算法和動態規劃演算法動態規劃
- 演算法筆記之動態規劃(4)演算法筆記動態規劃
- 動態規劃演算法原理與實踐動態規劃演算法
- 動態規劃演算法(DP)學習<1>動態規劃演算法
- 動態規劃之 KMP 演算法詳解動態規劃KMP演算法
- 矩陣連乘(動態規劃演算法)矩陣動態規劃演算法
- Swift 演算法實戰之路:動態規劃Swift演算法動態規劃
- 演算法提高 數的劃分 動態規劃 無序演算法動態規劃
- 使用動態規劃 實現字元級Diff & Patch動態規劃字元
- 動態規劃分析動態規劃
- 動態規劃(DP)動態規劃
- 動態規劃初步動態規劃
- 模板 - 動態規劃動態規劃
- 動態規劃法動態規劃
- 乾貨:圖解演算法——動態規劃系列圖解演算法動態規劃
- 聊一聊前端演算法面試——動態規劃前端演算法面試動態規劃
- 大廠常考動態規劃演算法題動態規劃演算法
- 演算法基礎--遞迴和動態規劃演算法遞迴動態規劃
- 最小總和問題(動態規劃演算法)動態規劃演算法
- 動態規劃演算法——裝最多水的容器動態規劃演算法
- 一文讀懂動態規劃演算法動態規劃演算法