【C++ 算法进阶】算法提升十五
股票问题1 (动态规划)
题目
本题为LC原题 题目如下
题目分析
因为股票肯定要有卖出的时机 所以说我们可以围绕这一点来进行动态规划
我们设置一个dp数组 假设每个位置的dp值就是当前卖出股票能获利的最大值
而卖出能获利的最大值肯定要前面以最少的价格买入
所以说我们需要一个min来继续前面能买股票的最小值
代码
class Solution {
public:
int maxProfit(vector<int>& prices) {
vector<int> dp(prices.size() , 0);
dp[0] = 0;
int minp = prices[0];
for (int i = 1; i < prices.size(); i++) {
dp[i] = prices[i] - minp;
if (dp[i] < 0) {
dp[i] = 0;
}
if (prices[i] < minp) {
minp = prices[i];
}
}
int ans = 0;
for (auto x : dp) {
ans = max(x , ans);
}
return ans;
}
};
股票问题2 (动态规划)
题目
本题为LC原题 题目如下
题目分析
本题的含义就是让我们抓住每一波的行情 也就是说一旦股票有升值的区间 我们就能够从该区间获利
那么问题就变成了 股票升值的区间有多少
从而就可以转化为计算出相邻两个股票升值多少 最后将所有结果一加就能得出最终答案了
代码
class Solution {
public:
int maxProfit(vector<int>& prices) {
vector<int> dp(prices.size() , 0);
dp[0] = 0;
int minp = prices[0];
for (int i = 1; i < prices.size(); i++) {
dp[i] = prices[i] - minp;
if (dp[i] < 0) {
dp[i] = 0;
}
if (prices[i] < minp) {
minp = prices[i];
}
}
int ans = 0;
for (auto x : dp) {
ans = max(x , ans);
}
return ans;
}
};
股票问题3 4(动态规划)
3 4 问题的本质是一题 第三题是第四题的特化版本 所以说我们只看第四题
题目
本题为LC原题 题目如下
题目分析
这是一个从左到右范围尝试模型 我们只需要加上一个K次的业务限制就能完成
首先分析下如果是0次交易我们获得利润是多少 如果只能在第0天交易利润是多少呢?
接下来分析普遍位置 比如说 dp[8][3]
- 它可能是8位置不参与交易 在0~7位置交易了三次
- 它可能是在8位置卖 在7位置买
- 它可能是在8位置卖 在6位置买
- …
接着我们找到上面所有可能性的最大值即可
代码
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
if (prices.empty()) return 0;
int n = prices.size();
if (k >= n / 2) { // 当交易次数 k 大于等于 n/2 时,相当于可以无限次交易
int maxProfit = 0;
for (int i = 1; i < n; i++) {
if (prices[i] > prices[i - 1]) {
maxProfit += prices[i] - prices[i - 1];
}
}
return maxProfit;
}
vector<vector<int>> dp(k + 1, vector<int>(n, 0));
for (int i = 1; i <= k; i++) {
int maxDiff = -prices[0]; // 初始化最大差值
for (int j = 1; j < n; j++) {
dp[i][j] = max(dp[i][j - 1], prices[j] + maxDiff);
maxDiff = max(maxDiff, dp[i - 1][j] - prices[j]);
}
}
return dp[k][n - 1];
}
};