diff --git a/Dynamic_Programming/3489.Zero-Array-Transformation-IV/3489.Zero-Array-Transformation-IV.cpp b/Dynamic_Programming/3489.Zero-Array-Transformation-IV/3489.Zero-Array-Transformation-IV.cpp new file mode 100644 index 000000000..5ffad9060 --- /dev/null +++ b/Dynamic_Programming/3489.Zero-Array-Transformation-IV/3489.Zero-Array-Transformation-IV.cpp @@ -0,0 +1,34 @@ +class Solution { + int dp[10][1001]; +public: + bool isOK(vector& nums) + { + for (int i=0; i& nums, vector>& queries) + { + for (int i=0; i=0; v--) + if (v>=d && dp[i][v-d] == true) + dp[i][v] = true; + } + if (isOK(nums)) return k+1; + } + return -1; + } +}; diff --git a/Dynamic_Programming/3489.Zero-Array-Transformation-IV/Readme.md b/Dynamic_Programming/3489.Zero-Array-Transformation-IV/Readme.md new file mode 100644 index 000000000..476ca9320 --- /dev/null +++ b/Dynamic_Programming/3489.Zero-Array-Transformation-IV/Readme.md @@ -0,0 +1,17 @@ +### 3489.Zero-Array-Transformation-IV + +这本质是一个背包问题。每处理一个query,在对应区间内的nums[i]就多得了一次删减的操作。 + +我们需要查看这些nums[i]在获得这个额外的删减机会之后,是否能连同之前的删减操作,实现置零?很显然,如果该query能够让nums[i]再削减d,那么就取决于nums[i]之前能否削减至d。 + +我们令dp[i][v]表示如果nums[i]的数值是v,能否最终削减成为零。就有 +``` +for q: queries + a = q[0], b = q[1], d = q[2]; + for (i=a; i=b; i++) { + for (int v=0; v<=1000; v++) { + dp[i][v] = dp[i][v] || d[i][v-d]; + } + } +``` +最终查看所有的dp[i][nums[i]]是否为true。 diff --git a/Others/3489.Zero-Array-Transformation-IV/3489.Zero-Array-Transformation-IV.cpp b/Others/3489.Zero-Array-Transformation-IV/3489.Zero-Array-Transformation-IV.cpp deleted file mode 100644 index e52102668..000000000 --- a/Others/3489.Zero-Array-Transformation-IV/3489.Zero-Array-Transformation-IV.cpp +++ /dev/null @@ -1,56 +0,0 @@ -class Solution { -public: - int minZeroArray(vector& nums, vector>& queries) - { - int n = nums.size(); - int left = 0, right = queries.size(); - while (left < right) - { - int mid = left+(right-left)/2; - if (isOK(nums, queries, mid)) - right = mid; - else - left = mid+1; - } - if (isOK(nums,queries, left)) return left; - else return -1; - } - - bool isOK(vector& nums, vector>& queries, int t) - { - int n = nums.size(); - vector>diff(n+1); - for (int i=0; iSet; - for (int i=0; i0) Set.insert(x); - else Set.erase(Set.lower_bound(-x)); - } - if (!subsetSum(Set, nums[i])) - return false; - } - return true; - } - - bool subsetSum(multiset& nums, int target) - { - vector dp(target + 1, false); - dp[0] = true; - for (int num : nums) - { - for (int j = target; j >= num; j--) { - if (dp[j - num]) - dp[j] = true; - } - } - return dp[target]; - } -}; diff --git a/Readme.md b/Readme.md index 5e7b25640..c89ddc8a7 100644 --- a/Readme.md +++ b/Readme.md @@ -857,6 +857,7 @@ [2518.Number-of-Great-Partitions](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/2518.Number-of-Great-Partitions) (H-) [2585.Number-of-Ways-to-Earn-Points](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/2585.Number-of-Ways-to-Earn-Points) (M) [2902.Count-of-Sub-Multisets-With-Bounded-Sum](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/2902.Count-of-Sub-Multisets-With-Bounded-Sum) (H) +[3489.Zero-Array-Transformation-IV](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/3489.Zero-Array-Transformation-IV) (H-) * ``键盘型`` [650.2-Keys-Keyboard](https://github.com/wisdompeak/LeetCode/blob/master/Dynamic_Programming/650.2-Keys-Keyboard) (M+) [651.4-Keys-Keyboard](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/651.4-Keys-Keyboard) (M+) @@ -1620,7 +1621,6 @@ [2963.Count-the-Number-of-Good-Partitions](https://github.com/wisdompeak/LeetCode/tree/master/Others/2963.Count-the-Number-of-Good-Partitions) (H-) [3009.Maximum-Number-of-Intersections-on-the-Chart](https://github.com/wisdompeak/LeetCode/tree/master/Others/3009.Maximum-Number-of-Intersections-on-the-Chart) (H) [3169.Count-Days-Without-Meetings](https://github.com/wisdompeak/LeetCode/tree/master/Others/3169.Count-Days-Without-Meetings) (M) -[3489.Zero-Array-Transformation-IV](https://github.com/wisdompeak/LeetCode/tree/master/Others/3489.Zero-Array-Transformation-IV) (H) * ``二维差分`` [850.Rectangle-Area-II](https://github.com/wisdompeak/LeetCode/tree/master/Others/850.Rectangle-Area-II) (H) [2132.Stamping-the-Grid](https://github.com/wisdompeak/LeetCode/tree/master/Others/2132.Stamping-the-Grid) (H) diff --git a/Recursion/3490.Count-Beautiful-Numbers/Readme.md b/Recursion/3490.Count-Beautiful-Numbers/Readme.md index 923b9750c..542d37d94 100644 --- a/Recursion/3490.Count-Beautiful-Numbers/Readme.md +++ b/Recursion/3490.Count-Beautiful-Numbers/Readme.md @@ -6,7 +6,7 @@ 1. 该位置是否贴近上限T。如果pos之前的选择都是贴着上限T,那么在第pos位上,我们的选择上限也只能是T[pos],否则上限可以是9. 2. 该位置是否是先导零。如果pos之前的选择全部都是0,那么在pos位置之前记录的乘积应该强制认作是1。这么做是为了处理这样一种情况:pos之前都是0,并且pos位也想取零。如果没有这条规则,那么递归到后面的乘积就永远是零了。 -由此,我们一旦做出了pos位置上的鞠策,在往后递归的时候,也需要相应更新isTight和isLeadingZero这两个状态。 +由此,我们一旦做出了pos位置上的决策,在往后递归的时候,也需要相应更新isTight和isLeadingZero这两个状态。 递归需要记忆化的支持。本题记忆化的状态就是递归函数的参数:pos, sum, product, isTight, isLeadingZero。我们可以用tuple作为key,加上有序map来存储访问过的状态。