<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>O(n^4) Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/on4/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/tag/on4/</link>
	<description></description>
	<lastBuildDate>Sat, 04 Aug 2018 06:14:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.0.8</generator>

<image>
	<url>https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/cropped-photo-32x32.jpg</url>
	<title>O(n^4) Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/tag/on4/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 546. Remove Boxes</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-546-remove-boxes/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-546-remove-boxes/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 03 Aug 2018 04:06:05 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[O(n^4)]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=3413</guid>

					<description><![CDATA[<p>Problem Given several boxes with different colors represented by different positive numbers. You may experience several rounds to remove boxes until there is no box&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-546-remove-boxes/">花花酱 LeetCode 546. Remove Boxes</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><iframe width="500" height="375" src="https://www.youtube.com/embed/wT7aS5fHZhs?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<h1><strong>Problem</strong></h1>
<p>Given several boxes with different colors represented by different positive numbers.<br />
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 &gt;= 1), remove them and get <code>k*k</code> points.<br />
Find the maximum points you can get.</p>
<p><b>Example 1:</b><br />
Input:</p><pre class="crayon-plain-tag">[1, 3, 2, 2, 2, 3, 4, 3, 1]</pre><p>Output:</p><pre class="crayon-plain-tag">23</pre><p>Explanation:</p>
<pre class="crayon:false">[1, 3, 2, 2, 2, 3, 4, 3, 1] 
----&gt; [1, 3, 3, 4, 3, 1] (3*3=9 points) 
----&gt; [1, 3, 3, 3, 1] (1*1=1 points) 
----&gt; [1, 1] (3*3=9 points) 
----&gt; [] (2*2=4 points)
</pre>
<p><b>Note:</b> The number of boxes <code>n</code> would not exceed 100.</p>
<p><img class="alignnone size-full wp-image-3425" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/546-ep214.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/546-ep214.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/546-ep214-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/546-ep214-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><img class="alignnone size-full wp-image-3426" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/546-ep214-2.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/546-ep214-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/546-ep214-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/546-ep214-2-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<h1>Solution: Recursion + Memorization</h1>
<p>Use dp[l][r][k] to denote the max score of subarray box[l] ~ box[r] with k boxes after box[r] that have the same color as box[r]</p>
<p><span style="color: #ff0000;">box[l]</span>, <span style="color: #339966;">box[l+1]</span>, &#8230;, <span style="color: #0000ff;">box[r], box[r+1], &#8230;, box[r+k]</span></p>
<p>e.g. &#8220;CDABACAAAAA&#8221;</p>
<p>dp[2][6][4] is the max score of [ABACA] followed by [AAAA]<br />
dp[2][6][3] is the max score of [ABACA] followed by [AAA]</p>
<pre class="crayon:false">base case: l &gt; r, empty array, return 0.</pre>
<pre class="crayon:false ">Transition:
dp[l][r][k] = max(dp[l][r-1][0] + (k + 1)*(k + 1),  # case 1
                  dp[l][i][k+1] + dp[i+1][r-1][0])  # case 2
# "ABACA|AAAA" 
# case 1: dp("ABAC") + score("AAAAA") drop j and the tail.
# case 2: box[i] == box[r], l &lt;= i &lt; r, try all break points
# max({dp("A|AAAAA") + dp("BAC")}, {dp("ABA|AAAAA") + dp("C")})</pre>
<p>Time complexity: O(n^4)</p>
<p>Space complexity: O(n^3)</p>
<p>C++</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 196 ms
class Solution {
public:
  int removeBoxes(vector&lt;int&gt;&amp; boxes) {
    const int n = boxes.size();
    m_ = vector&lt;vector&lt;vector&lt;int&gt;&gt;&gt;(n, vector&lt;vector&lt;int&gt;&gt;(n, vector&lt;int&gt;(n)));
    return dfs(boxes, 0, n - 1, 0);
  }
private:
  vector&lt;vector&lt;vector&lt;int&gt;&gt;&gt; m_;
  
  int dfs(const vector&lt;int&gt;&amp; boxes, int l, int r, int k) {
    if (l &gt; r) return 0;    
    if (m_[l][r][k] &gt; 0) return m_[l][r][k];
    m_[l][r][k] = dfs(boxes, l, r - 1, 0) + (k + 1) * (k + 1);
    for (int i = l; i &lt; r; ++i)
      if (boxes[i] == boxes[r])
        m_[l][r][k] = max(m_[l][r][k], dfs(boxes, l, i, k + 1) + dfs(boxes, i + 1, r - 1, 0));
    return m_[l][r][k];
  }
};</pre><p>Optimized</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 16 ms
int m[100][100][100];
class Solution {
public:
  int removeBoxes(vector&lt;int&gt;&amp; boxes) {    
    memset(m, 0, sizeof(m));
    return dfs(boxes, 0, boxes.size() - 1, 0);
  }
private:
  int dfs(const vector&lt;int&gt;&amp; boxes, int l, int r, int k) {
    if (l &gt; r) return 0;    
    if (m[l][r][k] &gt; 0) return m[l][r][k];
    int rr = r;
    int kk = k;
    while (l &lt; r &amp;&amp; boxes[r - 1] == boxes[r]) {--r; ++k;}
    m[l][r][k] = dfs(boxes, l, r - 1, 0) + (k + 1) * (k + 1);
    for (int i = l; i &lt; r; ++i)
      if (boxes[i] == boxes[r])
        m[l][r][k] = max(m[l][r][k], dfs(boxes, l, i, k + 1) + dfs(boxes, i + 1, r - 1, 0));
    for (int d = 1; d &lt;= r - rr; ++d)
      m[l][r + d][k - d] = m[l][r][k];
    return m[l][r][k];
  }
};</pre><p>Use a HashTable to replace the 3D DP array since the DP array could be sparse when many consecutive boxes are the same color.</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 8 ms (beats 100%)
class Solution {
public:
  int removeBoxes(vector&lt;int&gt;&amp; boxes) {
    len_ = vector&lt;int&gt;(boxes.size());
    for (int i = 1; i &lt; boxes.size(); ++i)
      if (boxes[i] == boxes[i - 1]) len_[i] = len_[i - 1] + 1;
    return dfs(boxes, 0, boxes.size() - 1, 0);
  }
private:
  unordered_map&lt;int, int&gt; m_;
  vector&lt;int&gt; len_;
  int dfs(const vector&lt;int&gt;&amp; boxes, int l, int r, int k) {
    if (l &gt; r) return 0;
    k += len_[r];
    r -= len_[r];
    int key = (l * 100 + r) * 100 + k;
    auto it = m_.find(key);
    if (it != m_.end()) return it-&gt;second;    
    int&amp; ans = m_[key];
    ans = dfs(boxes, l, r - 1, 0) + (k + 1) * (k + 1);
    for (int i = l; i &lt; r; ++i)
      if (boxes[i] == boxes[r])
        ans = max(ans, dfs(boxes, l, i, k + 1) + dfs(boxes, i + 1, r - 1, 0));
    return ans;
  }
};</pre><p></p>
<h1><strong>Related Problems</strong></h1>
<ul>
<li><a href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-312-burst-balloons/">花花酱 LeetCode 312. Burst Balloons</a></li>
<li><a href="https://zxi.mytechroad.com/blog/searching/leetcode-488-zuma-game/">花花酱 LeetCode 488. Zuma Game</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-546-remove-boxes/">花花酱 LeetCode 546. Remove Boxes</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-546-remove-boxes/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
