第 444 场周赛——最大化交错和为 K 的子序列乘积
题目
题解
这题的数据量暴力是能过的,找出子序列可以用dfs,然后需要注意中间的剪枝。对dfs,当前位u、当前交错和sum、当前乘积这三个参数是轻而易举就能想到的,对于当前是奇偶位也需要一个参数odd来记录,最后题目要求非空我们可以再用一个empty参数记录。我们可以首先看看所有的值加起来是否比 \(\left| k \right|\) 小,如果这都比 \(\left| k \right|\) 小,直接输出-1。如果ans达到了limit就说明这是最大的情况直接输出即可。如果mul超过了limit不一定就是非法了,他可以乘以0达到合法状态,但是如果ans已经>=0就没必要了,直接退出。最后遍历到最后一个数,此时如果非空且sum=k而且mul没有超过limit,ans记录最大值。但是这题需要set来记录状态是否被枚举过,被枚举过直接退出,否则会超时,可能会卡在这里。可以重点学一下这个哈希表是怎么记录的。
参考代码
class Solution {
public:
int maxProduct(vector<int>& nums, int k, int limit) {
int total = reduce(nums.begin(), nums.end());
if(total < abs(k)) return -1;
int n = nums.size();
int ans = -1;
unordered_set<long long> vis;
auto dfs = [&](this auto&& dfs, int u, int sum, int mul, bool odd, bool empty) -> void{
if(ans == limit || mul > limit && ans >= 0) return;
if(u == n) {
if(!empty && sum == k && mul <= limit) ans = max(ans, mul);
return;
}
long long mask = (long long) u << 32 | (sum + total) << 15 | mul << 2 | odd << 1 | empty;
if (!vis.insert(mask).second) {
return;
}
dfs(u + 1, sum, mul, odd, empty);
dfs(u + 1, sum + (odd?-nums[u]:nums[u]), min(mul * nums[u], limit + 1), !odd, false);
};
dfs(0, 0, 1, false, true);
return ans;
}
};

浙公网安备 33010602011771号