【01背包】LeetCode 3489. 零数组变换 IV
题目
https://leetcode.cn/problems/zero-array-transformation-iv/
题解
遍历 \(nums\),计算出每一项至少需要用 \(quries\) 的前几项进行 01 背包来恰好构成,若存在无法构成的,说明无解,输出 \(-1\),否则最后取最大值就是答案。
参考代码
bitset<1007> dp("1");//使用bitset优化dp
class Solution {
public:
int minZeroArray(vector<int>& nums, vector<vector<int>>& queries) {
int ans = 0, n = nums.size(), m = queries.size();
//枚举 nums 数组全部元素
for (int i = 0; i < n; ++ i) {
//nums[i] 本就为 0 的话则无需构造,直接略过
if (!nums[i]) continue;
//将 dp 数组置空
for (int j = 1; j <= nums[i]; ++ j) dp[j] = 0;
//01 背包:使用 queries 前 j 个元素构造出 nums[i]
for (int j = 0; j < m; ++ j) {
//不在合法下标范围,直接略过
if (queries[j][0] > i || queries[j][1] < i) continue;
//状态转移方程
for (int k = nums[i] - queries[j][2]; k >= 0; -- k) if (dp[k]) dp[k + queries[j][2]] = 1;
//已经可以构造出 nums[i],维护最大答案后退出循环
if (dp[nums[i]]) {
ans = max(ans, j + 1);
break;
}
}
//存在无法构造的情况,说明使用 queries 全部元素也无法满足要求
if (!dp[nums[i]]) return -1;
}
return ans;
}
};
浙公网安备 33010602011771号