You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
class Solution {
public int maxProfit(int[] prices) {
int n = prices.length;
int[] suf = new int[n];
int max = prices[n - 1];
for (int i = n - 2; i >= 0; --i) {
suf[i] = Math.max(suf[i + 1], max - prices[i]);
max = Math.max(max, prices[i]);
}
int min = prices[0], ans = 0;
for (int i = 1; i < n; ++i) {
ans = Math.max(ans, prices[i] - min + (i + 1 < n ? suf[i + 1] : 0));
min = Math.min(min, prices[i]);
}
return ans;
}
}
class Solution {
public int maxProfit(int[] prices) {
int n = prices.length;
if (n == 1) return 0;
final int K = 2;
int[][] dp = new int[K + 1][n];
for (int k = 1; k <= K; ++k) {
int min = prices[0];
for (int i = 1; i < n; ++i) {
for (int j = 1; j < i; ++j) {
min = Math.min(min, prices[j] - dp[k - 1][j - 1]);
}
dp[k][i] = Math.max(dp[k][i - 1], prices[i] - min);
}
}
return dp[K][n - 1];
}
}
class Solution {
public int maxProfit(int[] prices) {
int n = prices.length;
if (n == 1) return 0;
final int K = 2;
int[][] dp = new int[K + 1][n];
for (int k = 1; k <= K; ++k) {
int min = prices[0];
for (int i = 1; i < n; ++i) {
min = Math.min(min, prices[i - 1] - (i - 2 >= 0 ? dp[k - 1][i - 2] : 0));
dp[k][i] = Math.max(dp[k][i - 1], prices[i] - min);
}
}
return dp[K][n - 1];
}
}
class Solution {
public int maximizeWin(int[] prizePositions, int k) {
int l = 0, r = 0;
int ans = 0;
int[] dp = new int[prizePositions.length + 1];
while (r < prizePositions.length) {
while (prizePositions[l] < prizePositions[r] - k && l < r) {
++l;
}
dp[r + 1] = Math.max(dp[r], r - l + 1);
ans = Math.max(ans, r - l + 1 + dp[l]);
++r;
}
return ans;
}
}
The text was updated successfully, but these errors were encountered:
Woodyiiiiiii
changed the title
Leetcode 2555. Maximize Win From Two Segments
Leetcode 123. Best Time to Buy and Sell Stock III
Feb 7, 2023
Woodyiiiiiii
changed the title
Leetcode 123. Best Time to Buy and Sell Stock III
Leetcode 123. Best Time to Buy and Sell Stock III / IV
Feb 10, 2023
Woodyiiiiiii
changed the title
Leetcode 123. Best Time to Buy and Sell Stock III / IV
Leetcode 123. Best Time to Buy and Sell Stock III / IV / Minimum White Tiles
Feb 10, 2023
123. Best Time to Buy and Sell Stock III / IV
这两道题跟下面周赛的题目类似,也是DP的做法,可以扩展到k维度。
类似题目:
我的思路是:对于[0,i],我知道[0, j] (j<=i)的最大segment,那如何去求[j, i]的segment呢?所以卡在了这里。
下面是最好理解的做法,延伸了我的思考,不妨计算[j,i]时改成计算i=n-1时的最大segment:
那如果严谨点呢?就要建造二维dp数组dp[k + 1][n]了。其中dp[i][j]表示分成i个segment下的[0,j]的最大segment。容易得到递推方程
dp[k, i] = max(dp[k, i-1], prices[i] - prices[j] + dp[k-1, j-1]), j=[0..i-1]
。建立k+1宽度的数组是因为考虑到k=1的情况。容易得到如下写法:
为什么是
prices[j] - dp[k - 1][j - 1]
呢?因为最后要计算prices[i] - min
,所以要min
最小。但显然O(k * n^2)是超时了,可以发现min被重复计算了,同样用DP的思想可以继续简化:
总结:
非常有技巧的DP思维;k维度的递推公式计算及简化。
2555. Maximize Win From Two Segments
先看条件:
这道题是双周赛第三题,我想了很久没做出来,感觉不应该呀:我的思路是用二分法,但无法写出移动函数,因为主要矛盾还是条件2,如何选出2个k长度。
那么需要转换思维了,从题目条件出发,想到合适的解决问题的模型。首先k长度的segment,我们可以通过滑动窗口找到k范围内的最大prize数目;然后如何选2个segment使之和最大?或者说k个segment最大?那就要用到动态规划了。滑动窗口到i位置,找到[i-k,i]范围内最大后,使用之前积累的dp得到[0,i-k]范围最大prize数目的segment,更新答案,最后更新dp。
同理,如果题目是k个segment,也是同样的做法,dp扩展成二维数组,长度为k。
总结:
The text was updated successfully, but these errors were encountered: