動態規劃問題(C++版本)
動態規劃(dynamic programming)是運籌學的一個分支,是求解決策過程(decision process)最優化的數學方法。
本文將通過幾個例子來逐步向大家介紹動態規劃。
首先應用動態規劃區去解決問題是有條件的:1求最優化問題;2可以將問題拆解成小問題。
題目解讀:有一組數表示某支股票每天的價格,找到最大收益。應用動態規劃來解決這個問題我們首先要看看是不是滿足那兩個條件:1本題是求最優解的;2如何拆解成小問題?
大問題是求最大收益,那麼小問題可以寫成遍歷股票價格,比較當前時刻賣出的話可以獲得的最大收益是多少!
通過這個解釋可以看到把大問題拆解成小問題也是有要求的:小問題和大問題的性質需要保持一致,而且求解小問題的最終目標是得到大問題的解。所以求當前時刻賣出股票可以得到的最大收益,到最後一天的時候就得到這個大問題的解。
class Solution {
public:
int maxProfit(vector<int> &prices) {
int maxPro = 0;
int minPrice = INT_MAX;
for(int i = 0; i < prices.size(); i++){
minPrice = min(minPrice, prices[i]);//儲存在遍歷的過程價格最小值
maxPro = max(maxPro, prices[i] - minPrice);//儲存遍歷的過程中收益最大值
}
return maxPro;
}
};
這個問題非常簡單,用動態規劃的思路來解答這個問題可以對動態規劃有個簡單的認識。
題目解讀:這是一個爬樓梯的題目,你一步可以爬一個臺階或者兩個臺階,每個臺階都是收費的,你需要支付這個費用才能從這個臺階往上爬。爬到頂點的最低費用是多少?
這個問題同樣是求最優解的問題,看看這個問題拆解成小問題是怎樣的?
這個問題是求到達頂點的最低費用,那麼小問題就是到達每個臺階且從該臺階往上爬的最低費用。那麼到了頂點之後只需要看一下倒數第一和倒數第二兩個臺階往上爬的費用即可比較出到達頂點的最低費用。
怎麼得到到達每個臺階且從該臺階往上爬的最低費用?
dp[i]=cost[i]+min(dp[i-1],dp[i-2])
class Solution { public: int minCostClimbingStairs(vector<int>& cost) { int n=(int)cost.size(); vector<int> dp(n); dp[0]=cost[0]; dp[1]=cost[1]; for (int i=2; i<n; ++i) dp[i]=cost[i]+min(dp[i-2],dp[i-1]); return min(dp[n-2],dp[n-1]); } };
這個例子相比與例1稍微難一點,但是用動態規劃的思路去解也是非常簡單的。
例3. 01揹包問題
01揹包問題是非常經典的問題,也是動態規劃的代表問題。這裡我就不多解釋了,參考文章裡講的非常好。