zoukankan      html  css  js  c++  java
  • python算法动态规划

    python动态规划

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

    ​ 动态规划要点:最优子结构,边界,状态转移函数。

    最优子结构:在每个阶段最优状态可以从之前某个阶段的状态直接得到
    边界:最小子集的解
    状态转移函数:从一个阶段向另一个阶段过渡的具体形式,描述两个相邻子问题之间关系
    

    几个简单例子:

    1.爬楼梯源于LeetCode

    假设你正在爬楼梯,需要n阶才能到达楼顶
    每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
    注意:给定 n 是一个正整数。
    如:
    示例1:
        输入: 2
        输出: 2
        解释: 有两种方法可以爬到楼顶。
        1.  1 阶 + 1 阶
        2.  2 阶
    示例2:
        输入: 3
        输出: 3
        解释: 有三种方法可以爬到楼顶。
        1.  1 阶 + 1 阶 + 1 阶
        2.  1 阶 + 2 阶
        3.  2 阶 + 1 阶
    
    • 解析:

      如果给的两个示例看的不是特别清楚,你可以当阶梯为0,那么上楼梯方法0种这是必然,当阶梯只有1那么上楼梯方法只有1种:
      当4个台阶:
      	输入:4
      	输出:4
      	1. 1阶 + 1阶 + 1阶 + 1阶
      	2. 2阶 + 2阶
      	3. 1阶 + 2阶 + 1阶
      	4. 2阶 + 1阶 + 1阶
      	5. 1阶 + 1阶 + 2阶
      那么得到:
        阶梯数		爬楼梯方法
      	0			0
      	1			1
      	2			2
      	3			3
      	4			5
      	...
      如果感觉看的不明显可以推理一下5阶,6阶...
      可以得到当我们想爬n阶楼梯,我们可以得到: p(n-1) + p(n-2)		p为爬楼梯方法
      
    • 代码

      class Solution:
          def climbStairs(self, n: int) -> int:
              num_list = [0,1,2]
              if n==1:
                  return num_list[1]
              elif n==2:
                  return num_list[2]
              else:
                  for i in range(3,n+1):
                      num_list.append(num_list[i-1]+num_list[i-2])
              print(num_list)
              return num_list[n]
      
      obj = Solution()
      result = obj.climbStairs(10)
      print(result)
      
    • 提交LeetCode只击败了12.72%的人。通过优化

      class Solution:
          def climbStairs(self, n: int) -> int:
              a,b,c = 0,1,2
              if n == 1:
                  return b
              if n == 2:
                  return c
              while n>0:
                  c = a + b
                  a,b = b,c
                  n -= 1
              return c
      obj = Solution()
      result = obj.climbStairs(8)
      

    2.最子序列求和LeetCode

    53. 最大子序和
    给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
    
    示例:
    
    输入: [-2,1,-3,4,-1,2,1,-5,4],
    输出: 6
    解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
    
    • 解析:
    对于上述序列:
    nums = [-2,1,-3,4,-1,2,1,-5,4],当i从0~len(nums).其对应子序列和可以得到:
    dp = [-2, 1, -2, 4, 3, 5, 6, 1, 5] # dp[i]代表从0~i区间,所包含i元素的连续子数组,最大之和。
    
    • 代码:
    class Solution(object):
        def maxSubArray(self, nums):
            """
            :type nums: List[int]
            :rtype: int
            """
    
            #        判断边界
            if len(nums) == 0:
                return 0
            #         定义一个表格进行存储上一个子问题的最优解
            d = []
            d.append(nums[0])  # 第一个最优解为第一个元素
            max_ = nums[0]  # 返回的最大值
            for i in range(1, len(nums)):
                if nums[i] > nums[i] + d[i - 1]:
                    d.append(nums[i])
                else:
                    d.append(nums[i] + d[i - 1])
                if max_ < d[i]:
                    max_ = d[i]
                print(d)
    obj = Solution()
    result = obj.maxSubArray([-2,1,-3,4,-1,2,1,-5,4])
    print(result)
    
    

    3.买卖股票的最佳时机;ettCode

    给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
    
    如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。
    
    注意你不能在买入股票前卖出股票。
    
    示例 1:
    
    输入: [7,1,5,3,6,4]
    输出: 5
    解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
         注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。
    示例 2:
    
    输入: [7,6,4,3,1]
    输出: 0
    解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
    
    • 解析:
    	定义一个变量记录买入最小金额。定义一个数组存放每天最大利润。若当天利润大于前一天利润加入数组中,若当天利润小于前一天利润,则让当天利润等于前一天利润,并加入数组中。
    
    • 代码:
    class Solution:
        def maxProfit(self, prices: List[int]) -> int:
            if len(prices) <= 1:
                return 0
            profit = [0,]
            # 买入最低价格
            min_v = prices[0]
            for i in range(1,len(prices)):
                max_profit = max(profit[i-1],prices[i]-min_v)
                profit.append(max_profit)
                if prices[i] < min_v:
                    min_v = prices[i]
            return profit[-1]
    
    obj = Solution()
    res = obj.maxProfit([7,1,5,3,6,4])
    print(res)
    
  • 相关阅读:
    MapReduce 基础
    HDFS 快照(了解)
    HDFS 回收站(了解)
    HDFS 数据拷贝
    微信小程序(9)——多个空格写法
    react中使用jsonp跨域
    docker 介绍
    事务,悲观锁和乐观锁
    接口幂等性
    分布式爬虫
  • 原文地址:https://www.cnblogs.com/xujunkai/p/12591855.html
Copyright © 2011-2022 走看看