第 318 场周赛
Date: 2022-11-06
A 对数组执行操作
遍历即可
复杂度分析
- 时间复杂度:\(O(n)\)
- 空间复杂度:\(O(n)\)
B 长度为 K 子数组中的最大和
滑动窗口维护程度为 \(k\) 的和,然后用哈希表记录其中每个数字出现的次数,\(cnt\) 记录出现的种类数。
复杂度分析
- 时间复杂度:\(O(n)\)
- 空间复杂度:\(O(n)\)
C 雇佣 K 位工人的总代价
设置两个指针 \(l\) 和 \(r\),分别指向左右两边的边界,然后用一个优先队列来维护候选集即可。
复杂度分析
- 时间复杂度:\(O(n\log n)\)
- 空间复杂度:\(O(n)\)
D 最小移动总距离
设 \(d[i][j]\) 表示前 \(i\) 个工厂修了 \(m\) 个机器人的代价。转移时:
\[d[i][j] = min_{k=0}^n (d[i - 1][k] + cost_{p=k+1}^j dist(p,i))\]
class Solution {
public:
long long minimumTotalDistance(vector<int>& robot, vector<vector<int>>& factory) {
sort(robot.begin(), robot.end());
sort(factory.begin(), factory.end());
using ll = long long;
int n = robot.size(), m = factory.size();
vector<vector<ll>> d(m + 1, vector<ll>(n + 1, 1E15));
d[0][0] = 0;
ll res = 1E15;
for (int i = 1; i <= m; i++) {
int fac_pos = factory[i - 1][0], cnt = factory[i - 1][1];
for (int j = 0; j <= n; j++) {
d[i][j] = min(d[i][j], d[i - 1][j]);
}
for (int j = 0; j < n; j++) {
ll sum = 0;
for (int k = j; k < n; k++) {
if (k - j + 1 > cnt) break;
sum += abs(robot[k] - fac_pos);
d[i][k + 1] = min(d[i][k + 1], d[i - 1][j] + sum);
}
}
res = min(res, d[i][n]);
}
return res;
}
};
复杂度分析
- 时间复杂度:\(O(n^2m)\)
- 空间复杂度:\(O(nm)\)
另外这个题也可以用费用流来求解,把它视作一个带权二分图匹配问题。
当然,还有更巧妙地做法,是通过把工厂平铺成容量为 1 的工厂,这样 DP 会更好写。
本文访问 次