Maximize Score After N Operations
HardArrayMathDynamic ProgrammingBacktrackingBit ManipulationNumber TheoryBitmask
Solution
export function maxScore(nums: number[]): number {
const gcd = (x: number, y: number): number => {
return y === 0 ? x : gcd(y, x % y);
};
const n = nums.length;
const memo = new Array<number>(1 << nums.length).fill(-1);
const backtracking = (mask: number, pairsPicked: number) => {
if (2 * pairsPicked === n) {
return 0;
}
if (memo[mask] !== -1) {
return memo[mask];
}
let maxScore = 0;
for (let firstIndex = 0; firstIndex < n; firstIndex++) {
for (let secondIndex = firstIndex + 1; secondIndex < n; secondIndex++) {
if (((mask >> firstIndex) & 1) === 1 || ((mask >> secondIndex) & 1) === 1) {
continue;
}
const newMask = mask | (1 << firstIndex) | (1 << secondIndex);
const currentScore = (pairsPicked + 1) * gcd(nums[firstIndex], nums[secondIndex]);
const remainingScore = backtracking(newMask, pairsPicked + 1);
maxScore = Math.max(maxScore, currentScore + remainingScore);
}
}
return (memo[mask] = maxScore);
};
return backtracking(0, 0);
}