1799. Maximize Score After N Operations
Description
You are given nums
, an array of positive integers of size 2 * n
. You must perform n
operations on this array.
In the ith
operation (1-indexed), you will:
- Choose two elements,
x
andy
. - Receive a score of
i * gcd(x, y)
. - Remove
x
andy
fromnums
.
Return the maximum score you can receive after performing n
operations.
The function gcd(x, y)
is the greatest common divisor of x
and y
.
Example 1:
Input: nums = [1,2] Output: 1 Explanation: The optimal choice of operations is: (1 * gcd(1, 2)) = 1
Example 2:
Input: nums = [3,4,6,8] Output: 11 Explanation: The optimal choice of operations is: (1 * gcd(3, 6)) + (2 * gcd(4, 8)) = 3 + 8 = 11
Example 3:
Input: nums = [1,2,3,4,5,6] Output: 14 Explanation: The optimal choice of operations is: (1 * gcd(1, 5)) + (2 * gcd(2, 4)) + (3 * gcd(3, 6)) = 1 + 4 + 9 = 14
Constraints:
1 <= n <= 7
nums.length == 2 * n
1 <= nums[i] <= 106
Solutions
Solution: Dynamic Programming + Bit Manipulation
- Time complexity: O(2n*n2)
- Space complexity: O(2n)
JavaScript
js
/**
* @param {number[]} nums
* @return {number}
*/
const maxScore = function (nums) {
const n = nums.length;
const totalMask = (1 << n) - 1;
const dp = Array.from({ length: totalMask + 1 }, () => -1);
const gcd = (a, b) => (b ? gcd(b, a % b) : a);
const receiveScore = (mask, i) => {
if (mask === totalMask) return 0;
if (dp[mask] !== -1) return dp[mask];
let result = 0;
for (let a = 0; a < n - 1; a++) {
if (mask & (1 << a)) continue;
for (let b = a + 1; b < n; b++) {
if (mask & (1 << b)) continue;
const score = i * gcd(nums[a], nums[b]);
const nextMask = mask | (1 << a) | (1 << b);
const totalScore = score + receiveScore(nextMask, i + 1);
result = Math.max(totalScore, result);
}
}
dp[mask] = result;
return result;
};
return receiveScore(0, 1);
};