101 Logo
onenoughtone

Decision Making Pattern

What is the Decision Making Pattern?

The Decision Making Pattern in dynamic programming involves making optimal choices at each step to build the overall optimal solution.

It's characterized by having multiple options at each state, and we need to decide which option leads to the optimal result.

When to Use the Decision Making Pattern

The Decision Making Pattern is useful when:

  • You have multiple choices at each step
  • You need to find the optimal sequence of decisions
  • The problem involves maximizing or minimizing a value
  • The problem can be broken down into a series of decisions

Decision Making Template

  1. Define the state: What information do we need to make a decision at each step?
  2. Identify the decisions: What choices do we have at each step?
  3. Formulate the recurrence relation: How does the current state depend on previous states and the decision made?
  4. Implement the solution using either memoization or tabulation

Example: House Robber

Here's a solution for the House Robber problem, where you need to decide which houses to rob to maximize the amount of money:

function rob(nums) { // Handle edge cases if (!nums || nums.length === 0) return 0; if (nums.length === 1) return nums[0]; // Create a DP array where dp[i] represents the maximum amount // that can be robbed up to house i const dp = new Array(nums.length); // Base cases dp[0] = nums[0]; // If there's only one house, rob it dp[1] = Math.max(nums[0], nums[1]); // If there are two houses, rob the one with more money // Fill the DP array for (let i = 2; i < nums.length; i++) { // At each house, we have two choices: // 1. Rob the current house and add it to the max amount robbed up to i-2 // 2. Skip the current house and take the max amount robbed up to i-1 dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]); } // Return the maximum amount that can be robbed return dp[nums.length - 1]; } // Example usage: console.log(rob([1, 2, 3, 1])); // Output: 4 (rob house 1 and 3) console.log(rob([2, 7, 9, 3, 1])); // Output: 12 (rob house 1, 3, and 5)

Example: Best Time to Buy and Sell Stock

Here's a solution for the Best Time to Buy and Sell Stock problem, where you need to decide when to buy and sell a stock to maximize profit:

function maxProfit(prices) { // Handle edge cases if (!prices || prices.length <= 1) return 0; let maxProfit = 0; let minPrice = prices[0]; // Iterate through the prices for (let i = 1; i < prices.length; i++) { // Update the minimum price seen so far minPrice = Math.min(minPrice, prices[i]); // Update the maximum profit if selling at the current price // would result in a higher profit maxProfit = Math.max(maxProfit, prices[i] - minPrice); } return maxProfit; } // Example usage: console.log(maxProfit([7, 1, 5, 3, 6, 4])); // Output: 5 (buy at 1, sell at 6) console.log(maxProfit([7, 6, 4, 3, 1])); // Output: 0 (no profit possible)

Example: Jump Game

Here's a solution for the Jump Game problem, where you need to decide how many steps to jump at each position to reach the end:

function canJump(nums) { // Handle edge cases if (!nums || nums.length === 0) return false; if (nums.length === 1) return true; // Initialize the maximum reachable position let maxReach = nums[0]; // Iterate through the array for (let i = 0; i < nums.length; i++) { // If we can't reach the current position, return false if (maxReach < i) return false; // Update the maximum reachable position maxReach = Math.max(maxReach, i + nums[i]); // If we can reach the last index, return true if (maxReach >= nums.length - 1) return true; } // If we've gone through the entire array and haven't reached the end, // it's not possible to reach the end return false; } // Example usage: console.log(canJump([2, 3, 1, 1, 4])); // Output: true (jump 1 step from index 0 to 1, then 3 steps to the last index) console.log(canJump([3, 2, 1, 0, 4])); // Output: false (you will always arrive at index 3 with value 0, which means you can't reach the last index)

Key Insights

  • State Definition: Clearly define what information you need to make a decision at each step
  • Decision Space: Identify all possible decisions at each state
  • Optimal Substructure: Ensure that the optimal solution can be built from optimal solutions to subproblems
  • Greedy vs. DP: Some decision problems can be solved greedily, but many require DP to find the optimal solution
IntroVisualizePatternsPractice
101 Logo
onenoughtone