动态规划Ⅱ
一:买卖股票 I
• 给定一个数组,表示每天的股票价格。
• 你可以进行一次交易(先买再卖),问如何能得到最大利润。
def maxProfit(prices): if len(prices) < 2: return 0 min_price = prices[0] max_profit = 0 for price in prices: if price < min_price: min_price = price if price - min_price > max_profit: max_profit = price - min_price return max_profit
二、买卖股票 II
• 给定一个数组,表示每天的股票价格。
• 你可以进行任意多次的交易(先买再卖,在再次买入的时候必须将之前的股票卖出)
,问如何能得到最大利润
def maxProfit2(prices): max_profit = 0 for i in range(1, len(prices)): max_profit += max(0, prices[i] - prices[i - 1]) return max_profit
三、买卖股票 III
• 给定一个数组,表示每天的股票价格。
• 你可以进行任意多次的交易(先买再卖,在再次买入的时候必须将之前的股票卖出)
,每次交易需要缴纳手续费K元,问如何能得到最大利润。
#O(N) O(1)
def maxProfit3(prices, fee): cash, hold = 0, -prices[0] for i in range(1, len(prices)): cash, hold = max(cash, hold + prices[i] - fee), max(hold, cash - prices[i]) return cash
四、买卖股票 IV
• 给定一个数组,表示每天的股票价格。
• 你可以进行两次的交易(先买再卖,在再次买入的时候必须将之前的股票卖出),问
如何能得到最大利润。
• 输入: prices = [2, 4, 6, 1, 3, 8, 3]
• 输出: 11([2,6]、[1,8]是两次进行买入卖出的时机)
def maxProfit4(prices): total_max_profit = 0 n = len(prices) left_profits = [0] * n min_price = float('inf') for i in range(n): min_price = min(min_price, prices[i]) total_max_profit = max(total_max_profit, prices[i] - min_price) left_profits[i] = total_max_profit max_profit = 0 max_price = float('-inf') for i in range(n - 1, 0, -1): max_price = max(max_price, prices[i]) max_profit = max(max_profit, max_price - prices[i]) total_max_profit = max(total_max_profit, max_profit + left_profits[i - 1]) return total_max_profit
• 给定一个数组,表示每天的股票价格。
• 你可以进行K次的交易(先买再卖,在再次买入的时候必须将之前的股票卖出),问如
何能得到最大利润。
• 输入: prices = [3,2,6,5,0,3], k = 2
• 输出: 7
#O(n*k) def maxProfit5(prices, k): if len(prices) < 2: return 0 if len(prices) <= k / 2: maxProfit(prices) local = [0] * (k+1) globl = [0] * (k+1) for i in range(1, len(prices)): diff = prices[i] - prices[i - 1] j = k while j > 0: local[j] = max(globl[j - 1], local[j] + diff) globl[j] = max(globl[j], local[j]) j -= 1 return globl[k]
• 给定一个数组,表示每天的股票价格。
• 你可以进行任意多次的交易(先买再卖,在再次买入的时候必须将之前的股票卖出)
,但卖过之后需要休息一天,(卖掉股票之后的一天不允许买入),问如何能得到最
大利润。
• 输入: prices = [1,2,3,0,2]
• 输出: 3
• transactions = [buy, sell, cooldown, buy, sell]
def maxProfit6(prices): if len(prices) < 2: return 0 n = len(prices) sell = [0] * n buy = [0] * n sell[0] = 0; buy[0] = -prices[0] for i in range(1, n): sell[i] = max(sell[i - 1], buy[i - 1] + prices[i]) buy[i] = max(buy[i - 1], (sell[i - 2] if i > 1 else 0) - prices[i]) return sell[-1]
二维动态规划:
七、独特路径
• 一个机器人被放置在棋盘的左上角,棋盘有(m*n)个格子。机器人只可以往下移动或
者往右移动。机器人的目标是到达右下角(如图)
• 可以有多少种不重复的路径:
• 进阶问题:目前考虑如果在棋盘中有一些路障。计算不重复的路径
![](https://img2020.cnblogs.com/blog/1509441/202005/1509441-20200507115145682-639439035.png)
def uniquePaths(m, n): aux = [1 for x in range(n)] for i in range(1, m): for j in range(1, n): aux[j] = aux[j]+aux[j-1] return aux[-1]
def uniquePathsWithObstacles(obstacleGrid): M, N = len(obstacleGrid), len(obstacleGrid[0]) dp = [1] + [0] * (N-1) for i in range(M): for j in range(N): if obstacleGrid[i][j] == 1: dp[j] = 0 elif j > 0: dp[j] += dp[j-1] return dp[N-1]
• 给定一个有n行n列的棋盘。每个格子上有不同的值代表该格子的价值。目标是找到获
利最大的移动路线(从第一行的某个格子到最后一行的某个格子)
• 移动方法:
• 1. 移动到下一行的之前一列(up then left)
• 2. 移动到下一行(UP)
• 3.移动到下一行的下一列(UP then right)
def movingBoard(board): result = board m = len(board) n = len(board[0]) for i in range(1, m): for j in range (0, n): result[i][j] = max(0 if j == 0 else result[i-1][j-1], \ result[i-1][j], \ 0 if j == n-1 else result[i-1][j+1] ) \ + board[i][j] return max(result[-1])
空间优化:
def movingBoard2(board): result = board[0] m = len(board) n = len(board[0]) for i in range(1, m): for j in range (0, n): result[j] = max(0 if j == 0 else result[j-1], \ result[j], \ 0 if j == n-1 else result[j+1] ) \ + board[j] return max(result)
• 给定一个二维01矩阵,从中找出最大的全1正方形矩阵并返回其面积移动方法
def maximalSquare(matrix): if matrix == []: return 0 m, n = len(matrix), len(matrix[0]) dp = [[0] * n for x in range(m)] ans = 0 for x in range(m): for y in range(n): dp[x][y] = int(matrix[x][y]) if x and y and dp[x][y]: dp[x][y] = min(dp[x - 1][y - 1], dp[x][y - 1], dp[x - 1][y]) + 1 ans = max(ans, dp[x][y]) return ans * ans
空间优化:
def maximalSquare(matrix): if matrix == []: return 0 m, n = len(matrix), len(matrix[0]) dp = matrix[0] ans = 0 for x in range(0, m): for y in range(0, n): dp[y] = int(matrix[x][y]) if matrix[x][y]: dp[y] = min(dp[y - 1], dp[y - 1], dp[y]) + 1 ans = max(ans, dp[y]) return ans * ans