Skip to content
RSS feed tkhwang on GitHub tkhwang on Twitter

πŸ€– leetcode 1770. Maximum Score from Performing Multiplication Operations | hard | dynamic-programming | javascript

πŸ—’οΈ Problems

Maximum Score from Performing Multiplication Operations - LeetCode

You are given two 0-indexed integer arrays nums and multipliers of size n and m respectively, where n >= m.

You begin with a score of 0. You want to perform exactly m operations. On the ith operation (0-indexed) you will:

- Choose one integer x from either the start or the end of the array nums.
- Add `multipliers[i] * x` to your score.
  - Note that multipliers[0] corresponds to the first operation, multipliers[1] to the second operation, and so on.
  - Remove x from nums.

Return the maximum score after performing m operations.
Input: nums = [1,2,3], multipliers = [3,2,1]
Output: 14
Explanation: An optimal solution is as follows:
- Choose from the end, [1,2,3], adding 3 * 3 = 9 to the score.
- Choose from the end, [1,2], adding 2 * 2 = 4 to the score.
- Choose from the end, [1], adding 1 * 1 = 1 to the score.
The total score is 9 + 4 + 1 = 14.

πŸ€” First attempt

  • iλ²ˆμ§Έμ—μ„œ μ™Όμͺ½ ν˜Ήμ€ 였λ₯Έμͺ½μ„ μ„ νƒν•˜κ³ , 이 선택에 λ”°λΌμ„œ λ―Έλž˜μ— 영ν–₯을 λ―ΈμΉ˜λ―€λ‘œ dynamic programming 이라 생각함.
  • greedy 라면 ν˜„μž¬ 큰 μͺ½λ§Œμ„ μ„ νƒν•˜λ©΄ λ˜κ² μ§€λ§Œ ν˜„μž¬ μž‘μ€ κ±° μ„ νƒν•œ 이후에 μ•„μ£Ό 큰 값이 μˆ¨μ–΄ μžˆμ„ 수 μžˆμœΌλ―€λ‘œ greedy ν•œ 선택이 닡이 될 μˆ˜λŠ” μ—†μŒ.

✨ Idea

  • 0λ²ˆμ§ΈλΆ€ν„° μ™Όμͺ½, 였λ₯Έμͺ½ 선택을 recursive 둜 계산
    • μ™Όμͺ½ 선택 μ‹œ nums[left] * multipliers[times] + dfs(left + 1, times + 1)
    • 였λ₯Έμͺ½ 선택 μ‹œ nums[right] * multipliers[times] + dfs(left, times + 1)
    • ν˜„μž¬ λ‹¨κ³„μ—μ„œλŠ” recursive 둜 계산 이 두 κ°’ μ€‘μ—μ„œ 큰 값을 return
  • 이λ₯Ό multipliers[] λκΉŒμ§€ 계산

πŸ€ Intuition

이 λ¬Έμ œμ—μ„œ κ°€μž₯ μ–΄λ €μ› λ˜ 뢀뢄은 ν•œ 번 선택을 ν•œ λ‹€μŒμ— μ΄ν›„μ—λŠ” μ„ νƒλœ 값을 λ°°μ œν•œ array μ—μ„œ 선택을 ν•΄μ•Όν•˜λŠ”λ° 이 λΆ€λΆ„ μ²˜λ¦¬κ°€ μ–΄λ €μ› μŒ. μ„ νƒν•œ 값을 μ§€μš΄ arrayλ₯Ό 계속 가지고 κ°€μ•Ό ν–ˆλŠ”λ°... 쒋은 방법이 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

λ‹€μŒ κ²½μš°μ— right index λŠ” μžλ™ 계산이 κ°€λŠ₯ν• κΉŒμš” ?

  • 주어진 nums array 의 length λŠ” N.
  • ν˜„μž¬ μ™Όμͺ½ index κ°€ left
  • ν˜„μž¬ 총 선택 횟수 times

πŸ’‘ [object Object] λŠ” μžλ™ 계산 κ°€λŠ₯ν•œκ°€ ?

λͺ¨λ“  것을 였λ₯Έμͺ½μ—μ„œλ§Œ μ„ νƒν•œλ‹€λ©΄

right = N - 1 - times;

times μ€‘μ—μ„œ λͺ‡ λ²ˆμ€ left μ—μ„œ 선택을 ν–ˆλ‹€λ©΄

  • 맀번 였λ₯Έμͺ½μ—μ„œλ§Œ μ„ νƒν–ˆλ‹€λ©΄ times 만큼 쀄어듀텐데
  • κ·Έμ€‘μ—μ„œ left λ§ŒνΌμ€ μ™Όμͺ½μ—μ„œ 선택을 ν–ˆμœΌλ―€λ‘œ 였λ₯Έμͺ½μ€ 그만큼 쀄어듀지 μ•Šμ•„λ„ 됨.
right = N - 1 - (times - left);

πŸ•ΈοΈβ¬‡οΈπŸ”₯ top-down Solution

const N = nums.length;
const NM = multipliers.length;

const cache = {};
const genKey = (left, times) => `${left}:${times}`;

const dfs = (left, times) => {
  const key = genKey(left, times);

  if (times >= NM) return 0;
  if (cache[key] !== undefined) return cache[key];

  const right = N - 1 - (times - left);

  const leftValue = nums[left] * multipliers[times] + dfs(left + 1, times + 1);
  const rightValue = nums[right] * multipliers[times] + dfs(left, times + 1);

  return (cache[key] = Math.max(leftValue, rightValue));
};

return dfs(0, 0);