Formatted question description: https://leetcode.ca/all/1799.html

1799. Maximize Score After N Operations

Level

Hard

Description

You are given nums, an array of positive integers of size 2 * n. You must perform n operations on this array.

In the i-th 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] <= 10^6

Solution

In this problem, the 2 * n numbers in nums need to be divided into n groups, where each group contains 2 numbers. Find all possible combinations, and for each combination, calculate the score accordingly. Finally, return the maximum score.

class Solution {
    int maxScore = 0;
    Map<Long, Integer> map = new HashMap<Long, Integer>();

    public int maxScore(int[] nums) {
        int length = nums.length;
        int[] groups = new int[length];
        groups[0] = 1;
        for (int i = 1; i < length; i++) {
            groups[i] = 1;
            backtrack(nums, groups, 1, 2, nums.length / 2);
            groups[i] = 0;
        }
        return maxScore;
    }

    public void backtrack(int[] nums, int[] groups, int startIndex, int curr, int n) {
        int length = nums.length;
        if (curr > n) {
            int[][] groupsNums = new int[length][2];
            for (int i = 0; i < length; i++) {
                groupsNums[i][0] = groups[i];
                groupsNums[i][1] = nums[i];
            }
            Arrays.sort(groupsNums, new Comparator<int[]>() {
                public int compare(int[] groupNum1, int[] groupNum2) {
                    return groupNum1[0] - groupNum2[0];
                }
            });
            int[] gcds = new int[n];
            for (int i = 0; i < length; i += 2) {
                int gcd = gcd(groupsNums[i][1], groupsNums[i + 1][1]);
                gcds[i / 2] = gcd;
            }
            Arrays.sort(gcds);
            int score = 0;
            for (int i = 0; i < n; i++)
                score += (i + 1) * gcds[i];
            maxScore = Math.max(maxScore, score);
            return;
        }
        for (int i = startIndex; i < length; i++) {
            if (groups[i] == 0) {
                groups[i] = curr;
                for (int j = i + 1; j < length; j++) {
                    if (groups[j] == 0) {
                        groups[j] = curr;
                        backtrack(nums, groups, i + 1, curr + 1, n);
                        groups[j] = 0;
                    }
                }
                groups[i] = 0;
            }
        }
    }

    public int gcd(int num1, int num2) {
        return num2 == 0 ? num1 : gcd(num2, num1 % num2);
    }
}

All Problems

All Solutions