class Solution {
public:
int findMaxValueOfEquation(vector<vector<int>>& points, int k) {
int ans = -1e9;
deque<int> q;
for (int i = 0; i < points.size(); i++) {
// while x[j] < x[i] - k, 删除过期的j
while (!q.empty() && points[q.front()][0] < points[i][0] - k)
q.pop_front();
// ans = max(ans, y[i] + x[i] + y[j] - x[j])
if (!q.empty())
ans = max(ans, points[i][1] + points[i][0] + points[q.front()][1] - points[q.front()][0]);
// y[j]-x[j]递减的队列。且因为i不是候选项,所以先维护单调队列,再入队i
while (!q.empty() && points[q.back()][1] - points[q.back()][0] <= points[i][1] - points[i][0])
q.pop_back();
q.push_back(i);
}
return ans;
}
};
/*
yi + yj + |xi - xj| max
假设j<i,则为 yi + yj + xi - xj max
固定i,则为 yj - xj max
且 |xi - xj| <= k
已假设j<i,则满足 xi - xj <= k
综上,题目化为————
求 “yj - xj 在 j 满足 j < i 且 xj >= xi - k 条件下最大值”
*/
class Solution {
public:
int maxSubarraySumCircular(vector<int>& nums) {
// 处理环形,可以复制一份接在后面,成为2n的数组
// [1...n][n+1...2n]
int n = nums.size();
nums.insert(nums.begin(), 0);
vector<int> preSum(2 * n + 1, 0);
preSum[0] = 0;
for (int i = 1; i <= n; i++)
preSum[i] = preSum[i - 1] + nums[i];
for (int i = n + 1; i <= 2 * n; i++)
preSum[i] = preSum[i - 1] + nums[i - n];
int ans = -1e9;
deque<int> q;
for (int i = 1; i <= 2 * n; i++) {
// j 的范围 [i-n, i-1]
// 当 j < i - n 删除
while (!q.empty() && q.front() < i - n)
q.pop_front();
if (!q.empty())
ans = max(ans, preSum[i] - preSum[q.front()]);
while (!q.empty() && preSum[q.back()] >= preSum[i])
q.pop_back();
q.push_back(i);
}
return ans;
}
};
-
312. 戳气球 - 力扣(LeetCode)
法一:区间DP
class Solution {
public:
int maxCoins(vector<int>& nums) {
int n = nums.size();
nums.insert(nums.begin(), 1);
nums.push_back(1);
vector<vector<int>> f(n + 2, vector<int>(n + 2, 0));
for (int len = 1; len <= n; len++) // 区间动态规划,最外层循环其区间长度
for (int l = 1; l <= n - len + 1; l++) { // 然后循环左端点
int r = l + len - 1; // 计算出右端点
for (int p = l; p <= r; p++)
f[l][r] = max(f[l][r], f[l][p - 1] + f[p + 1][r] + nums[p] * nums[l - 1] * nums[r + 1]);
}
return f[1][n];
}
};
法二:递归+记忆化
class Solution {
public:
int maxCoins(vector<int>& nums) {
int n = nums.size();
nums.insert(nums.begin(), 1);
nums.push_back(1);
this->nums = nums;
f = vector<vector<int>>(n + 2, vector<int>(n + 2, -1));
return calc(1, n);
}
private:
vector<int> nums;
vector<vector<int>> f;
int calc(int l, int r) {
if (l > r) return 0;
if (f[l][r] != -1) return f[l][r];
for (int p = l; p <= r; p++)
f[l][r] = max(f[l][r], calc(l, p - 1) + calc(p + 1, r) + nums[p] * nums[l - 1] * nums[r + 1]);
return f[l][r];
}
};
class Solution {
public:
int mergeStones(vector<int>& stones, int k) {
int n = stones.size();
vector<vector<vector<int>>> f(n, vector<vector<int>>(n, vector<int>(k + 1, 1e9)));
for (int i = 0; i < n; i++) f[i][i][1] = 0;
for (int len = 2; len <= n; len++)
for (int l = 0; l < n - len + 1; l++) {
int r = l + len - 1;
for (int i = 2; i <= k; i++)
for (int p = l; p < r; p++)
f[l][r][i] = min(f[l][r][i], f[l][p][1] + f[p + 1][r][i - 1]);
int sum = 0;
for (int i = l; i <= r; i++) sum += stones[i];
f[l][r][1] = min(f[l][r][1], f[l][r][k] + sum);
}
return f[0][n - 1][1] == 1e9 ? -1 : f[0][n - 1][1];
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int rob(TreeNode* root) {
f.insert({nullptr, {0, 0}});
dfs(root);
return max(f[root][1], f[root][0]);
}
private:
unordered_map<TreeNode*, vector<int>> f;
void dfs(TreeNode* root) {
if (root == nullptr) return;
dfs(root->left);
dfs(root->right);
f.insert({root, {0, 0}});
f[root][0] = max(f[root->left][0], f[root->left][1]) + max(f[root->right][0], f[root->right][1]);
f[root][1] = f[root->left][0] + f[root->right][0] + root->val;
}
};
class Solution {
public:
int numSquares(int n) {
vector<int> f(n + 1, 1e9);
f[0] = 0;
for (int i = 1; i * i <= n; i++)
for (int j = i * i; j <= n; j++)
f[j] = min(f[j], f[j - i * i] + 1);
return f[n];
}
};
class Solution {
public:
bool canJump(vector<int>& nums) {
int n = nums.size();
int farthest = 0;
for (int i = 0; i < n; i++)
if (i <= farthest) {
farthest = max(farthest, i + nums[i]);
if (farthest >= n - 1) return true;
}
return false;
}
};