第十周(Dynamic ProgrammingIV)
目录:
- 本周完成题目
- 主要过程思路
- 相关代码
一、本周完成题目
本周共完成2道题目,2道Medium。主要是继续针对于所学的Dynamic Programming选择了一些题目进行练习。
具体完成题目及难度如下表:
# | Title | Difficulty |
---|---|---|
62 | Unique Paths | Medium |
309 | Best Time to Buy and Sell Stock with Cooldown | Medium |
题目内容
1、Unique Paths
A robot is located at the top-left corner of a m x n grid (marked ‘Start’ in the diagram below).
The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked ‘Finish’ in the diagram below).
How many possible unique paths are there?
题目大意:一个机器人在一个m*n的格子的左上角,只能向右或者向下移动,问移动到右下角有多少种移动路径。
2、Best Time to Buy and Sell Stock with Cooldown
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times) with the following restrictions:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
After you sell your stock, you cannot buy stock on next day. (ie, cooldown 1 day)
Example:
prices = [1, 2, 3, 0, 2]
maxProfit = 3
transactions = [buy, sell, cooldown, buy, sell]
题目大意:买卖股票求最大利润。每天只能进行一次操作,且每次卖出股票后需要空一天时间不再买进。
二、主要过程思路
本周的题目使用到了Dynamic Programming的思想,简单来说需要从逐步到整体,动态操作最后得到需要的结果。
1、Unique Paths:
本题比较简单。我开始的想法是,对于每个坐标为i,j的格子,要到达这个格子有两种路径。所以到达这个格子的路径数可以表示为:dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 。设定i,j进行循环操作求出右下角即可。
但是这种方法在空间时间上都比较慢,参考了其他方法对于这个方法做了优化。
参考代码
主要思路是对于上面提到的内容进行合并。将dp[i - 1][j] + dp[i][j - 1]合并为一个数字。具体公式如下:
vector<int> cur(m, 1);
for (int j = 1; j < n; j++)
for (int i = 1; i < m; i++)
cur[i] += cur[i - 1];
return cur[m - 1];
2、Best Time to Buy and Sell Stock with Cooldown:
依然是动态规划的方式。此题需要维护三个一维数组buy, sell,和rest。其中:
buy[i]表示在第i天之前最后一个操作是买,此时的最大收益。
sell[i]表示在第i天之前最后一个操作是卖,此时的最大收益。
rest[i]表示在第i天之前最后一个操作是冷冻期,此时的最大收益。
根据题目设定,可以写出递推式为:
buy[i] = max(rest[i-1] - price, buy[i-1])
sell[i] = max(buy[i-1] + price, sell[i-1])
rest[i] = max(sell[i-1], buy[i-1], rest[i-1])
这样,可以将上面三个递推式精简到两个:
buy[i] = max(sell[i-2] - price, buy[i-1])
sell[i] = max(buy[i-1] + price, sell[i-1])
还可以做进一步优化,由于i只依赖于i-1和i-2,所以我们可以设定presell和prebuy,在O(1)的空间复杂度完成算法。
三、相关代码
Unique Paths
class Solution {
public:
int uniquePaths(int m, int n) {
vector<vector<int> > dp(m, vector<int> (n, 1));
for (int i = 1; i < m; i++)
for (int j = 1; j < n; j++)
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
return dp[m - 1][n - 1];
}
};
Best Time to Buy and Sell Stock with Cooldown
class Solution {
public:
int maxProfit(vector<int>& prices) {
int buy = INT_MIN, pre_buy = 0, sell = 0, pre_sell = 0;
for (int price : prices) {
pre_buy = buy;
buy = max(pre_sell - price, pre_buy);
pre_sell = sell;
sell = max(pre_buy + price, pre_sell);
}
return sell;
}
};