You are given two arrays nums and andValues of length n and m
respectively.
The value of an array is equal to the last element of that array.
You have to divide nums into mdisjoint contiguous subarrays such that for the ith subarray [li, ri], the bitwise AND of the subarray elements is equal to andValues[i], in other words, nums[li] & nums[li + 1] & ... & nums[ri] == andValues[i] for all 1 <= i <= m, where & represents the bitwise AND operator.
Return _theminimum possible sum of the values of the _msubarraysnumsis divided into. If it is not possible to dividenumsintomsubarrays satisfying these conditions, return-1.
Input: nums =[1,4,3,3,2], andValues =[0,3,3,2]Output: 12Explanation:
The only possible way to divide `nums`is:1.`[1,4]` as `1 & 4 == 0`.2.`[3]` as the bitwise `AND` of a single element subarray is that element itself.3.`[3]` as the bitwise `AND` of a single element subarray is that element itself.4.`[2]` as the bitwise `AND` of a single element subarray is that element itself.The sum of the values for these subarrays is`4 + 3 + 3 + 2 = 12`.
Input: nums =[2,3,5,7,7,7,5], andValues =[0,7,5]Output: 17Explanation:
There are three ways to divide `nums`:1.`[[2,3,5],[7,7,7],[5]]`with the sum of the values `5 + 7 + 5 == 17`.2.`[[2,3,5,7],[7,7],[5]]`with the sum of the values `7 + 7 + 5 == 19`.3.`[[2,3,5,7,7],[7],[5]]`with the sum of the values `7 + 7 + 5 == 19`.The minimum possible sum of the values is`17`.
Input: nums =[1,2,3,4], andValues =[2]Output: -1Explanation:
The bitwise `AND` of the entire array `nums`is`0`. As there is no possible
way to divide `nums` into a single subarray to have the bitwise `AND` of
elements `2`,return`-1`.
Since m (number of subarrays) is small, we can use DP to try all possible partitions. For each partition, we check if the subarray’s AND matches the required value and keep track of the minimum sum of last elements.
classSolution {
publicintminimumSum(int[] nums, int[] andValues) {
int n = nums.length, m = andValues.length;
int[][] dp =newint[n+1][m+1];
for (int[] d : dp) Arrays.fill(d, Integer.MAX_VALUE);
dp[0][0]=0;
for (int k=1;k<=m;k++) {
for (int i=k;i<=n;i++) {
int val=nums[i-1];
for (int j=i-1;j>=k-1;j--) {
val&=nums[j];
if (val==andValues[k-1]&& dp[j][k-1]!=Integer.MAX_VALUE)
dp[i][k]=Math.min(dp[i][k],dp[j][k-1]+nums[i-1]);
}
}
}
return dp[n][m]==Integer.MAX_VALUE?-1:dp[n][m];
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
classSolution {
funminimumSum(nums: IntArray, andValues: IntArray): Int {
val n = nums.size; val m = andValues.size
val dp = Array(n+1) { IntArray(m+1) { Int.MAX_VALUE } }
dp[0][0]=0for (k in1..m) {
for (i in k..n) {
var val_ = nums[i-1]
for (j in i-1 downTo k-1) {
val_ = val_ and nums[j]
if (val_==andValues[k-1] && dp[j][k-1]!=Int.MAX_VALUE)
dp[i][k]=minOf(dp[i][k],dp[j][k-1]+nums[i-1])
}
}
}
returnif (dp[n][m]==Int.MAX_VALUE) -1else dp[n][m]
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
classSolution:
defminimumSum(self, nums: list[int], andValues: list[int]) -> int:
n, m = len(nums), len(andValues)
dp = [[float('inf')] * (m+1) for _ in range(n+1)]
dp[0][0] =0for k in range(1, m+1):
for i in range(k, n+1):
val = nums[i-1]
for j in range(i-1, k-2, -1):
val &= nums[j]
if val == andValues[k-1] and dp[j][k-1] < float('inf'):
dp[i][k] = min(dp[i][k], dp[j][k-1] + nums[i-1])
return-1if dp[n][m] == float('inf') else dp[n][m]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
impl Solution {
pubfnminimum_sum(nums: Vec<i32>, and_values: Vec<i32>) -> i32 {
let n = nums.len(); let m = and_values.len();
letmut dp =vec![vec![i32::MAX; m+1]; n+1];
dp[0][0]=0;
for k in1..=m {
for i in k..=n {
letmut val = nums[i-1];
for j in (k-1..=i-1).rev() {
val &= nums[j];
if val==and_values[k-1] && dp[j][k-1]!=i32::MAX {
dp[i][k]=dp[i][k].min(dp[j][k-1]+nums[i-1]);
}
}
}
}
if dp[n][m]==i32::MAX { -1 } else { dp[n][m] }
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
classSolution {
minimumSum(nums: number[], andValues: number[]):number {
constn=nums.length, m=andValues.length;
constdp= Array.from({length:n+1},()=>Array(m+1).fill(Infinity));
dp[0][0]=0;
for (letk=1;k<=m;k++) {
for (leti=k;i<=n;i++) {
letval=nums[i-1];
for (letj=i-1;j>=k-1;j--) {
val&=nums[j];
if (val==andValues[k-1] &&dp[j][k-1]<Infinity)dp[i][k]=Math.min(dp[i][k],dp[j][k-1]+nums[i-1]); }
}
}
returndp[n][m]==Infinity?-1:dp[n][m]; }
}