Skip to content

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 and y.
  • Receive a score of i * gcd(x, y).
  • Remove x and y from nums.

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);
};

Released under the MIT license