码迷,mamicode.com
首页 > 其他好文 > 详细

[LeetCode] 动态规划入门题目

时间:2017-09-29 22:52:57      阅读:138      评论:0      收藏:0      [点我收藏+]

标签:http   toc   i++   ice   直接   i+1   local   是什么   情况   

最近接触了动态规划这个厉害的方法,还在慢慢地试着去了解这种思想,因此就在LeetCode上面找了几道比较简单的题目练了练手。

首先,动态规划是什么呢?很多人认为把它称作一种“算法”,其实我认为把它称作一种“思想”更为合适;利用动态规划去解决问题,其实就是逐步递推的过程,与贪心算法不同,动态规划递推的每一步都要求是当前的最优解(这是很重要的,递推的正确性依赖的就是这一点);利用动态规划解题时,必须自己定义出来状态和状态转移方程。然而,看上去简单,做起来却非常困难,因为解题时的具体形式千差万别,找出问题的子结构以及通过子结构重新构造最优解的过程很难统一。

经典的动态规划题目有背包问题、硬币问题等等,可以通过这些题目去理解一下这个东西。

我认为,动态规划最难的就是找出状态方程。同时,个人认为比较难的是,懂得去利用“前面每一步都是最优解”这一点。

废话不多说,直接看看LeetCode上简单的动态规划题目。

要注意的是,下面的三题都用到了局部最优和全局最优解法:

1.Jump Game

原题地址:https://leetcode.com/problems/jump-game/description/

解法:

用一个global变量保存到目前为止能跳的最远距离,用一个local变量保存当前一步出发能跳的最远距离,这题里面的状态就是走到每一步时的global[i]值,状态转移方程就是global[i] =max{nums[i] + i, global[i-1]}。当然,写代码的时候用变量代替数组即可。

class Solution {
public:
    bool canJump(vector<int>& nums) {
      int reach = 0;
      for (int i = 0; i < nums.size() - 1 && reach >= i; i++) {
          reach = nums[i] + i > reach ? nums[i] + i : reach;
      }
      return reach >= nums.size() - 1;
  }
};

 

2.Maximum Subarray

原题地址:https://leetcode.com/problems/maximum-subarray/description/

解法:

这一题要维护两个变量:global和local,与上面一题一样,local保存包含当前元素的最大值(局部最优),global保存的是所有情况里面的最大值(全局最优)。假设第i步的local[i]和global[i]已知,那么第i+1步的local[i + 1] = max{ nums[i] + local[i], nums[i + 1] },global[i + 1]  = max{global[i], local[i + 1]}。代码如下:

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
      int global = nums[0], local = nums[0];
      for (int i = 1; i < nums.size(); i++) {
          local = nums[i] > nums[i] + local ? nums[i] : nums[i] + local;
          global = local > global ? local : global;
      }       
      return global;
  }
};

 

3.Best Time to Buy and Sell Stock

原题地址:https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/

这道题目有两种方法,其实都是动态规划:

(1)

class Solution {
public:
   int maxProfit(vector<int>& prices) {
       if (prices.size() == 0) return 0; 
      int maxPrice = prices[prices.size() - 1];
      int res = 0;
      for (int i = prices.size() - 1; i >= 0; i--) {
          maxPrice = max(maxPrice, prices[i]);
          res = max(res, maxPrice - prices[i]);
      }
      return res;     
  }
};

这种解法在这个博客里面讲得很详细:http://www.cnblogs.com/remlostime/archive/2012/11/06/2757434.html

(2)局部最优和全局最优解法:

class Solution {
public:
   int maxProfit(vector<int>& prices) {
      if (prices.size() == 0) return 0;
      int local = 0, global = 0;
      for (int i = 1; i < prices.size(); i++) {
          local = max(0, local + prices[i] - prices[i - 1]);
          global = max(local, global);
      }
      return global;   
  }
};
local = max(0, local + prices[i] - prices[i - 1])这一句,我一开始在考虑:为什么不写成local = max(local, local + prices[i] - prices[i - 1])呢?
后来想了一下,因为假如这样写,有可能得到的就不是包含当前元素的局部最优解了。所以,在“局部最优和全局最优解法”里面,永远不会出现local=local的情况。

这篇文章讲的都是具体题目的解法,要真正理解动态规划,真的要多做题,多找规律。

[LeetCode] 动态规划入门题目

标签:http   toc   i++   ice   直接   i+1   local   是什么   情况   

原文地址:http://www.cnblogs.com/fengziwei/p/7612879.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!