Skip to content

Prepare For Coder Interview – Denny

  • Basic
  • Medium
  • Hard
  • Architect
  • Life

LeetCode: Remove Boxes

Posted on February 15, 2018July 26, 2020 by braindenny

Remove Boxes



Similar Problems:

  • CheatSheet: Leetcode For Code Interview
  • CheatSheet: Common Code Problems & Follow-ups
  • Tag: #dynamicprogramming, #game, #inspiring, #intervaldp

Given several boxes with different colors represented by different positive numbers.
You may experience several rounds to remove boxes until there is no box left. Each time you can choose some continuous boxes with the same color (composed of k boxes, k >= 1), remove them and get k*k points.
Find the maximum points you can get.

Example 1:
Input:

[1, 3, 2, 2, 2, 3, 4, 3, 1]

Output:

23

Explanation:

[1, 3, 2, 2, 2, 3, 4, 3, 1] 
----> [1, 3, 3, 4, 3, 1] (3*3=9 points) 
----> [1, 3, 3, 3, 1] (1*1=1 points) 
----> [1, 1] (3*3=9 points) 
----> [] (2*2=4 points)
Note: The number of boxes n would not exceed 100.

Github: code.dennyzhang.com

Credits To: leetcode.com

Leave me comments, if you have better ways to solve.


// https://code.dennyzhang.com/remove-boxes
// Basic Ideas: interval DP + greedy
//
//   Greedy: We shouldn't cut continous repeating subarray.
//     (p+q)*(p+q) >= p*p+q*q
//
//   f(i, j)
//       For the following continuous characters same as s[j]
//       
//       For all characters (s[p]) in between s[i] and s[j],
//          If s[p] == s[j], try to remove s[p+1...j-1]
//
// Complexity: Time O(n^4), Space O(n^3)
func dfs(dp [][][]int, i int, j int, k int, boxes []int) int {
    if i>j {
        return 0
    }

    // Already caculated, use cached value
    if dp[i][j][k] != 0 {
        return dp[i][j][k]
    }

    // find the continuous characters
    for i<j && boxes[j-1]==boxes[j] {
        j--
        k++
    }

    // remove s[j] with the continous same characters
    dp[i][j][k] = (k+1)*(k+1) + dfs(dp, i, j-1, 0, boxes)

    // interval DP
    for p:=i; p<j; p++ {
        if boxes[p] == boxes[j] {
           // Remove s[p+1...j-1], then attach s[j] to s[i...p]
            v := dfs(dp, p+1, j-1, 0, boxes) + dfs(dp, i, p, k+1, boxes)
            if v > dp[i][j][k] {
                dp[i][j][k] = v
            } 
        }
    }
    return dp[i][j][k]
}

func removeBoxes(boxes []int) int {
    dp := make([][][]int, len(boxes))
    for i, _ := range dp {
        dp[i] = make([][]int, len(boxes))
        for j, _ := range dp[i] {
            dp[i][j] = make([]int, 100)
        }
    }
    return dfs(dp, 0, len(boxes)-1, 0, boxes)
}
linkedin
github
slack

Post Views: 7
Posted in HardTagged #dynamicprogramming, #game, #inspiring, intervaldp, redo

Post navigation

LintCode: Digital Coverage
LeetCode: Maximum Gap

Leave a Reply Cancel reply

Your email address will not be published.

Tags

#array #backtracking #bfs #binarytree #bitmanipulation #blog #classic #codetemplate #combination #dfs #dynamicprogramming #game #graph #greedy #heap #inspiring #interval #linkedlist #manydetails #math #palindrome #recursive #slidingwindow #stack #string #subarray #trie #twopointer #twosum binarysearch editdistance hashmap intervaldp knapsack monotone oodesign presum rectangle redo review rotatelist series sql treetraversal unionfind

Recent Posts

  • a
  • a
  • a
  • a
  • a

Recent Comments

    Archives

    Categories

    • Amusing
    • Basic
    • Easy
    • Hard
    • Life
    • Medium
    • Resource
    • Review
    • Series
    • Uncategorized
    Proudly powered by WordPress | Theme: petals by Aurorum.