<?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>state compression Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/state-compression/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/tag/state-compression/</link>
	<description></description>
	<lastBuildDate>Wed, 25 Nov 2020 04:13:12 +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>state compression Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/tag/state-compression/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 1659. Maximize Grid Happiness</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1659-maximize-grid-happiness/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1659-maximize-grid-happiness/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 23 Nov 2020 06:27:48 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[state compression]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7709</guid>

					<description><![CDATA[<p>You are given four integers,&#160;m,&#160;n,&#160;introvertsCount, and&#160;extrovertsCount. You have an&#160;m x n&#160;grid, and there are two types of people: introverts and extroverts. There are&#160;introvertsCount&#160;introverts and&#160;extrovertsCount&#160;extroverts. You&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1659-maximize-grid-happiness/">花花酱 LeetCode 1659. Maximize Grid Happiness</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode 1659. Maximize Grid Happiness - 刷题找工作 EP371" width="500" height="281" src="https://www.youtube.com/embed/QC0A4L-xkYc?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>You are given four integers,&nbsp;<code>m</code>,&nbsp;<code>n</code>,&nbsp;<code>introvertsCount</code>, and&nbsp;<code>extrovertsCount</code>. You have an&nbsp;<code>m x n</code>&nbsp;grid, and there are two types of people: introverts and extroverts. There are&nbsp;<code>introvertsCount</code>&nbsp;introverts and&nbsp;<code>extrovertsCount</code>&nbsp;extroverts.</p>



<p>You should decide how many people you want to live in the grid and assign each of them one grid cell. Note that you&nbsp;<strong>do not</strong>&nbsp;have to have all the people living in the grid.</p>



<p>The&nbsp;<strong>happiness</strong>&nbsp;of each person is calculated as follows:</p>



<ul><li>Introverts&nbsp;<strong>start</strong>&nbsp;with&nbsp;<code>120</code>&nbsp;happiness and&nbsp;<strong>lose</strong>&nbsp;<code>30</code>&nbsp;happiness for each neighbor (introvert or extrovert).</li><li>Extroverts&nbsp;<strong>start</strong>&nbsp;with&nbsp;<code>40</code>&nbsp;happiness and&nbsp;<strong>gain</strong>&nbsp;<code>20</code>&nbsp;happiness for each neighbor (introvert or extrovert).</li></ul>



<p>Neighbors live in the directly adjacent cells north, east, south, and west of a person&#8217;s cell.</p>



<p>The&nbsp;<strong>grid happiness</strong>&nbsp;is the&nbsp;<strong>sum</strong>&nbsp;of each person&#8217;s happiness. Return<em>&nbsp;the&nbsp;<strong>maximum possible grid happiness</strong>.</em></p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2020/11/05/grid_happiness.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> m = 2, n = 3, introvertsCount = 1, extrovertsCount = 2
<strong>Output:</strong> 240
<strong>Explanation:</strong> Assume the grid is 1-indexed with coordinates (row, column).
We can put the introvert in cell (1,1) and put the extroverts in cells (1,3) and (2,3).
- Introvert at (1,1) happiness: 120 (starting happiness) - (0 * 30) (0 neighbors) = 120
- Extrovert at (1,3) happiness: 40 (starting happiness) + (1 * 20) (1 neighbor) = 60
- Extrovert at (2,3) happiness: 40 (starting happiness) + (1 * 20) (1 neighbor) = 60
The grid happiness is 120 + 60 + 60 = 240.
The above figure shows the grid in this example with each person's happiness. The introvert stays in the light green cell while the extroverts live on the light purple cells.
</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> m = 3, n = 1, introvertsCount = 2, extrovertsCount = 1
<strong>Output:</strong> 260
<strong>Explanation:</strong> Place the two introverts in (1,1) and (3,1) and the extrovert at (2,1).
- Introvert at (1,1) happiness: 120 (starting happiness) - (1 * 30) (1 neighbor) = 90
- Extrovert at (2,1) happiness: 40 (starting happiness) + (2 * 20) (2 neighbors) = 80
- Introvert at (3,1) happiness: 120 (starting happiness) - (1 * 30) (1 neighbor) = 90
The grid happiness is 90 + 80 + 90 = 260.
</pre>



<p><strong>Example 3:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> m = 2, n = 2, introvertsCount = 4, extrovertsCount = 0
<strong>Output:</strong> 240
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>1 &lt;= m, n &lt;= 5</code></li><li><code>0 &lt;= introvertsCount, extrovertsCount &lt;= min(m * n, 6)</code></li></ul>



<h2><strong>Solution: DP</strong></h2>



<figure class="wp-block-image size-large"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1659-ep371-1.png" alt="" class="wp-image-7712" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1659-ep371-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1659-ep371-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1659-ep371-1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></figure>



<figure class="wp-block-image size-large"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1659-ep371-2.png" alt="" class="wp-image-7713" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1659-ep371-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1659-ep371-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1659-ep371-2-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></figure>



<figure class="wp-block-image size-large"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1659-ep371-3.png" alt="" class="wp-image-7714" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1659-ep371-3.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1659-ep371-3-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1659-ep371-3-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></figure>



<figure class="wp-block-image size-large"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1659-ep371-4.png" alt="" class="wp-image-7715" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1659-ep371-4.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1659-ep371-4-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1659-ep371-4-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></figure>



<p>dp(x, y, in, ex, mask) := max score at (x, y) with in and ex left and the state of previous row is mask.</p>



<p>Mask is ternary, mask(i) = {0, 1, 2} means {empty, in, ex}, there are at most 3^n = 3^5 = 243 different states.</p>



<p>Total states / Space complexity: O(m*n*3^n*in*ex) = 5*5*3^5*6*6<br>Space complexity: O(m*n*3^n*in*ex)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">class Solution {
public:
  int getMaxGridHappiness(int m, int n, int introvertsCount, int extrovertsCount) {
    constexpr int kMaxStates = 243;
    int dp[6][6][7][7][kMaxStates];
    memset(dp, -1, sizeof(dp));
    auto get = [](int val, int i) { return val / static_cast&lt;int&gt;(pow(3, i)) % 3; };
    auto update = [](int val, int s) { return (val * 3 + s) % kMaxStates; };
    vector&lt;int&gt; init{0, 120, 40};
    vector&lt;int&gt; gain{0, -30, 20};
    
    function&lt;int(int,int,int,int,int)&gt; dfs = [&amp;](int x, int y, int in, int ex, int mask) {
      if (in == 0 &amp;&amp; ex == 0) return 0; // Nothing left.
      if (x == n) { x = 0; ++y; }
      if (y == m) return 0; // Done.
      int&amp; ans = dp[x][y][in][ex][mask];      
      if (ans != -1) return ans;
      
      ans = dfs(x + 1, y, in, ex, update(mask, 0)); // Skip current cell.
      
      vector&lt;int&gt; counts{0, in, ex};
      int up = get(mask, n - 1);
      int left = get(mask, 0);         
      for (int i = 1; i &lt;= 2; ++i) {
        if (counts[i] == 0) continue;        
        int s = init[i];
        if (y - 1 &gt;= 0 &amp;&amp; up) s += gain[i] + gain[up];
        if (x - 1 &gt;= 0 &amp;&amp; left) s += gain[i] + gain[left];
        ans = max(ans, s + dfs(x + 1, y, in - (i==1), ex - (i==2), update(mask, i)));
      }
      return ans;
    };
    return dfs(0, 0, introvertsCount, extrovertsCount, 0);
  }
};</pre>

</div><h2 class="tabtitle">Python3</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag"># Author: Huahua
class Solution:
  def getMaxGridHappiness(self, m: int, n: int, I: int, E: int) -&gt; int:    
    init, gain = [None, 120, 40], [None, -30, 20]
    
    get = lambda val, i: (val // (3 ** i)) % 3
    update = lambda val, s: (val * 3 + s) % (3 ** n)
    
    @lru_cache(None)
    def dp(x: int, y: int, i: int, e: int, mask: int) -&gt; int:
      if x == n: x, y = 0, y + 1
      if i + e == 0 or y == m: return 0
      
      ans = dp(x + 1, y, i, e, update(mask, 0))
      up, left = get(mask, n - 1), get(mask, 0)
      
      for cur, count in enumerate([i, e], 1):
        if count == 0: continue
        s = init[cur]
        if x - 1 &gt;= 0 and left: s += gain[cur] + gain[left]
        if y - 1 &gt;= 0 and up: s += gain[cur] + gain[up]
        ans = max(ans, s + dp(x + 1, y, 
                              i - (cur == 1), 
                              e - (cur == 2),
                              update(mask, cur)))
      return ans
    return dp(0, 0, I, E, 0)</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1659-maximize-grid-happiness/">花花酱 LeetCode 1659. Maximize Grid Happiness</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-1659-maximize-grid-happiness/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1494. Parallel Courses II</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1494-parallel-courses-ii/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1494-parallel-courses-ii/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 28 Jun 2020 05:41:08 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[bitmask]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[NP]]></category>
		<category><![CDATA[state compression]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6982</guid>

					<description><![CDATA[<p>Given the integer&#160;n&#160;representing the number of courses at some university labeled from&#160;1&#160;to&#160;n, and the array&#160;dependencies&#160;where&#160;dependencies[i] = [xi, yi]&#160;&#160;represents a prerequisite relationship, that is, the course&#160;xi&#160;must&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1494-parallel-courses-ii/">花花酱 LeetCode 1494. Parallel Courses II</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>Given the integer&nbsp;<code>n</code>&nbsp;representing the number of courses at some university labeled from&nbsp;<code>1</code>&nbsp;to&nbsp;<code>n</code>, and the array&nbsp;<code>dependencies</code>&nbsp;where&nbsp;<code>dependencies[i] = [x<sub>i</sub>, y<sub>i</sub>]</code>&nbsp;&nbsp;represents a prerequisite relationship, that is, the course&nbsp;<code>x<sub>i</sub></code>&nbsp;must be taken before the course&nbsp;<code>y<sub>i</sub></code>. &nbsp;Also, you are given the&nbsp;integer&nbsp;<code>k</code>.</p>



<p>In one semester you can take&nbsp;<strong>at most</strong>&nbsp;<code>k</code>&nbsp;courses as long as you have taken all the prerequisites for the courses you are taking.</p>



<p><em>Return the minimum number of semesters to take all courses</em>.&nbsp;It is guaranteed that you can take all courses in some way.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2020/05/22/leetcode_parallel_courses_1.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 4, dependencies = [[2,1],[3,1],[1,4]], k = 2
<strong>Output:</strong> 3 
<strong>Explanation:</strong> The figure above represents the given graph. In this case we can take courses 2 and 3 in the first semester, then take course 1 in the second semester and finally take course 4 in the third semester.
</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2020/05/22/leetcode_parallel_courses_2.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 5, dependencies = [[2,1],[3,1],[4,1],[1,5]], k = 2
<strong>Output:</strong> 4 
<strong>Explanation:</strong> The figure above represents the given graph. In this case one optimal way to take all courses is: take courses 2 and 3 in the first semester and take course 4 in the second semester, then take course 1 in the third semester and finally take course 5 in the fourth semester.
</pre>



<p><strong>Example 3:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 11, dependencies = [], k = 2
<strong>Output:</strong> 6
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>1 &lt;= n &lt;= 15</code></li><li><code>1 &lt;= k &lt;= n</code></li><li><code>0 &lt;=&nbsp;dependencies.length &lt;= n * (n-1) / 2</code></li><li><code>dependencies[i].length == 2</code></li><li><code>1 &lt;= x<sub>i</sub>, y<sub>i</sub>&nbsp;&lt;= n</code></li><li><code>x<sub>i</sub>&nbsp;!= y<sub>i</sub></code></li><li>All prerequisite relationships are distinct, that is,&nbsp;<code>dependencies[i] != dependencies[j]</code>.</li><li>The given graph is a directed acyclic graph.</li></ul>



<h2><strong>Solution: DP</strong> <strong>/ Bitmask</strong></h2>



<p>NOTE: This is a NP problem, any polynomial-time algorithm is incorrect otherwise P = NP.</p>



<p>Variant 1:<br>dp[m] := whether state m is reachable, where m is the bitmask of courses studied.<br>For each semester, we enumerate all possible states from 0 to 2^n &#8211; 1, if that state is reachable, then we choose c (c &lt;= k) courses from n and check whether we can study those courses.<br>If we can study those courses, we have a new reachable state, we set dp[m | courses] = true.</p>



<p>Time complexity: O(n*2^n*2^n) = O(n*n^4) &lt;&#8211; This will be much smaller in practice.<br>and can be reduced to O(n*3^n).<br>Space complexity: O(2^n)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua, 52 ms, 14.5 MB
class Solution {
public:
  int minNumberOfSemesters(int n, vector&lt;vector&lt;int&gt;&gt;&amp; dependencies, int k) {    
    const int S = 1 &lt;&lt; n;
    vector&lt;int&gt; deps(n); // deps[i] = dependency mask for course i.
    for (const auto&amp; d : dependencies)
      deps[d[1] - 1] |= 1 &lt;&lt; (d[0] - 1);    
    // dp(i)[s] := reachable(s) at semester i.
    vector&lt;int&gt; dp(S);
    dp[0] = 1;
    for (int d = 1; d &lt;= n; ++d) { // at most n semesters.
      vector&lt;int&gt; tmp(S); // start a new semesters.
      for (int s = 0; s &lt; S; ++s) {
        if (!dp[s]) continue; // not a reachable state.
        int mask = 0;
        for (int i = 0; i &lt; n; ++i)
          if (!(s &amp; (1 &lt;&lt; i)) &amp;&amp; (s &amp; deps[i]) == deps[i]) 
            mask |= (1 &lt;&lt; i);
        // Prunning, take all.
        if (__builtin_popcount(mask) &lt;= k) {
          tmp[s | mask] = 1;         
        } else {
          // Try all subsets. 
          for (int c = mask; c; c = (c - 1) &amp; mask)
            if (__builtin_popcount(c) &lt;= k) {
              tmp[s | c] = 1;
            }
        }
        if (tmp.back()) return d;
      }
      dp.swap(tmp);      
    }
    return -1;
  }
};</pre>
</div></div>



<p>Variant 2:<br>dp[m] := min semesters to reach state m.<br>dp[m | c] = min{dp[m | c], dp[m] + 1}, if we can reach m | c from m.<br>This allows us to get rid of enumerate n semesters.<br>Time complexity: O(2^n*2^n) &lt;&#8211; This will be much smaller in practice.<br>and can be reduced to O(3^n).<br>Space complexity: O(2^n)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua, 16 ms, 8.5 MB
class Solution {
public:
  int minNumberOfSemesters(int n, vector&lt;vector&lt;int&gt;&gt;&amp; dependencies, int k) {
    const int kInf = 1e9;
    const int S = 1 &lt;&lt; n;
    vector&lt;int&gt; deps(n); // deps[i] = dependency mask for course i.
    for (const auto&amp; d : dependencies)
      deps[d[1] - 1] |= 1 &lt;&lt; (d[0] - 1);    
    // dp[m] := min semesters to reach state m.
    vector&lt;int&gt; dp(S, kInf);
    dp[0] = 0;
    for (int s = 0; s &lt; S; ++s) {
      if (dp[s] == kInf) continue; // not reachable.
      // Generate a mask of courses we can study under state s.
      int mask = 0;
      for (int i = 0; i &lt; n; ++i)
        if (!(s &amp; (1 &lt;&lt; i)) &amp;&amp; (s &amp; deps[i]) == deps[i])
          mask |= (1 &lt;&lt; i);
      // Prunning, take all.
      if (__builtin_popcount(mask) &lt;= k) {
        dp[s | mask] = min(dp[s | mask], dp[s] + 1);       
      } else {
        // Try all subsets.
        for (int c = mask; c; c = (c - 1) &amp; mask)
          if (__builtin_popcount(c) &lt;= k)
            dp[s | c] = min(dp[s | c], dp[s] + 1);
      }
      // Early termination?
      if (dp.back() != kInf) return dp.back();
    }
    return dp.back();
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1494-parallel-courses-ii/">花花酱 LeetCode 1494. Parallel Courses II</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-1494-parallel-courses-ii/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1434. Number of Ways to Wear Different Hats to Each Other</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1434-number-of-ways-to-wear-different-hats-to-each-other/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1434-number-of-ways-to-wear-different-hats-to-each-other/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 04 May 2020 03:23:29 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[state compression]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6691</guid>

					<description><![CDATA[<p>There are&#160;n&#160;people&#160;and 40 types of hats labeled from 1 to 40. Given a list of list of integers&#160;hats, where&#160;hats[i]&#160;is a list of all hats preferred&#160;by&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1434-number-of-ways-to-wear-different-hats-to-each-other/">花花酱 LeetCode 1434. Number of Ways to Wear Different Hats to Each Other</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>There are&nbsp;<code>n</code>&nbsp;people&nbsp;and 40 types of hats labeled from 1 to 40.</p>



<p>Given a list of list of integers&nbsp;<code>hats</code>, where&nbsp;<code>hats[i]</code>&nbsp;is a list of all hats preferred&nbsp;by the&nbsp;<code>i-th</code>&nbsp;person.</p>



<p>Return the number of ways that the n people wear different hats to each other.</p>



<p>Since the answer&nbsp;may be too large,&nbsp;return it modulo&nbsp;<code>10^9 + 7</code>.</p>



<p><strong>Example 1:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> hats = [[3,4],[4,5],[5]]
<strong>Output:</strong> 1
<strong>Explanation: </strong>There is only one way to choose hats given the conditions. 
First person choose hat 3, Second person choose hat 4 and last one hat 5.</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> hats = [[3,5,1],[3,5]]
<strong>Output:</strong> 4
<strong>Explanation: </strong>There are 4 ways to choose hats
(3,5), (5,3), (1,3) and (1,5)
</pre>



<p><strong>Example 3:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> hats = [[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3,4]]
<strong>Output:</strong> 24
<strong>Explanation: </strong>Each person can choose hats labeled from 1 to 4.
Number of Permutations of (1,2,3,4) = 24.
</pre>



<p><strong>Example 4:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> hats = [[1,2,3],[2,3,5,6],[1,3,7,9],[1,8,9],[2,5,7]]
<strong>Output:</strong> 111
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>n == hats.length</code></li><li><code>1 &lt;= n &lt;= 10</code></li><li><code>1 &lt;= hats[i].length &lt;= 40</code></li><li><code>1 &lt;= hats[i][j] &lt;= 40</code></li><li><code>hats[i]</code>&nbsp;contains a list of&nbsp;<strong>unique</strong>&nbsp;integers.</li></ul>



<h2><strong>Solution: DP</strong></h2>



<p>dp[i][j] := # of ways using first i hats, j is the bit mask of people wearing hats.</p>



<p>e.g. dp[3][101] == # of ways using first 3 hats that people 1 and 3 are wearing hats.</p>



<p>init dp[0][0] = 1</p>



<p>dp[i][mask |  (1 &lt;&lt; p)] = dp[i-1][mask | (1 &lt;&lt; p)] + dp[i-1][mask], where people p prefers hats i.</p>



<p>ans: dp[nHat][1&#8230;1] </p>



<p>Time complexity: O(2^n * h * n)<br>Space complexity: O(2^n * h) -&gt; O(2^n)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int numberWays(vector&lt;vector&lt;int&gt;&gt;&amp; hats) {
    constexpr int kHat = 40;
    constexpr int kMod = 1e9 + 7;
    const int n = hats.size();    
    vector&lt;vector&lt;int&gt;&gt; people(kHat + 1); // hat -&gt; {people}
    for (int i = 0; i &lt; n; ++i)
      for (int hat : hats[i])
        people[hat].push_back(i);
    // dp[i][j] := # of ways using first i hats where j is bit mask of people wearing hats.
    vector&lt;vector&lt;int&gt;&gt; dp(kHat + 1, vector&lt;int&gt;(1 &lt;&lt; n));
    dp[0][0] = 1;
    
    for (int i = 1; i &lt;= kHat; ++i) {
      dp[i] = dp[i - 1];
      for (int mask = (1 &lt;&lt; n) - 1; mask &gt;= 0; --mask)
        for (int p : people[i]) {
          if (mask &amp; (1 &lt;&lt; p)) continue;
          dp[i][mask | (1 &lt;&lt; p)] += dp[i - 1][mask];
          dp[i][mask | (1 &lt;&lt; p)] %= kMod;          
        }
    }
    return dp.back().back();
  }
};</pre>
</div></div>



<p>O(2^n) memory</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int numberWays(vector&lt;vector&lt;int&gt;&gt;&amp; hats) {
    constexpr int kHat = 40;
    constexpr int kMod = 1e9 + 7;
    const int n = hats.size();    
    vector&lt;vector&lt;int&gt;&gt; people(kHat + 1); // hat -&gt; {people}
    for (int i = 0; i &lt; n; ++i)
      for (int hat : hats[i])
        people[hat].push_back(i);
    // dp([i])[j] := # of ways using first i hats where j is bit mask of people wearing hat.
    vector&lt;int&gt; dp(1 &lt;&lt; n);
    dp[0] = 1;
    
    for (int i = 1; i &lt;= kHat; ++i)      
      for (int mask = (1 &lt;&lt; n) - 1; mask &gt;= 0; --mask)
        for (int p : people[i]) {
          if (mask &amp; (1 &lt;&lt; p)) continue;
          dp[mask | (1 &lt;&lt; p)] += dp[mask];
          dp[mask | (1 &lt;&lt; p)] %= kMod;          
      }
    return dp.back();
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1434-number-of-ways-to-wear-different-hats-to-each-other/">花花酱 LeetCode 1434. Number of Ways to Wear Different Hats to Each Other</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-1434-number-of-ways-to-wear-different-hats-to-each-other/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
