动态规划问题(C++版本)

动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法。

本文将通过几个例子来逐步向大家介绍动态规划。

首先应用动态规划区去解决问题是有条件的:1求最优化问题;2可以将问题拆解成小问题。

例1. LeetCode 121 Best Time to Buy and Sell Stock

题目解读:有一组数表示某支股票每天的价格,找到最大收益。应用动态规划来解决这个问题我们首先要看看是不是满足那两个条件: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;
}
};

这个问题非常简单,用动态规划的思路来解答这个问题可以对动态规划有个简单的认识。

 例2. LeetCode 746 Min Cost Climbing Stairs

 题目解读:这是一个爬楼梯的题目,你一步可以爬一个台阶或者两个台阶,每个台阶都是收费的,你需要支付这个费用才能从这个台阶往上爬。爬到顶点的最低费用是多少?

 这个问题同样是求最优解的问题,看看这个问题拆解成小问题是怎样的?

 这个问题是求到达顶点的最低费用,那么小问题就是到达每个台阶且从该台阶往上爬的最低费用。那么到了顶点之后只需要看一下倒数第一和倒数第二两个台阶往上爬的费用即可比较出到达顶点的最低费用。

 怎么得到到达每个台阶且从该台阶往上爬的最低费用?

    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背包问题

 这里贴一个参考的文章:https://blog.csdn.net/mu399/article/details/7722810

 01背包问题是非常经典的问题,也是动态规划的代表问题。这里我就不多解释了,参考文章里讲的非常好。

    原文作者:动态规划
    原文地址: https://blog.csdn.net/leo_luo1/article/details/79964357
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞