<?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>TSP Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/tsp/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/tag/tsp/</link>
	<description></description>
	<lastBuildDate>Mon, 07 Dec 2020 05:26:21 +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>TSP Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/tag/tsp/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 1681. Minimum Incompatibility</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1681-minimum-incompatibility/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1681-minimum-incompatibility/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 07 Dec 2020 03:35:28 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[bitmask]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[TSP]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7777</guid>

					<description><![CDATA[<p>You are given an integer array&#160;nums​​​ and an integer&#160;k. You are asked to distribute this array into&#160;k&#160;subsets of&#160;equal size&#160;such that there are no two equal&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1681-minimum-incompatibility/">花花酱 LeetCode 1681. Minimum Incompatibility</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 1681. Minimum Incompatibility - 刷题找工作 EP374" width="500" height="281" src="https://www.youtube.com/embed/03KwgvDgxKg?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>You are given an integer array&nbsp;<code>nums</code>​​​ and an integer&nbsp;<code>k</code>. You are asked to distribute this array into&nbsp;<code>k</code>&nbsp;subsets of&nbsp;<strong>equal size</strong>&nbsp;such that there are no two equal elements in the same subset.</p>



<p>A subset&#8217;s&nbsp;<strong>incompatibility</strong>&nbsp;is the difference between the maximum and minimum elements in that array.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>minimum possible sum of incompatibilities</strong>&nbsp;of the&nbsp;</em><code>k</code>&nbsp;<em>subsets after distributing the array optimally, or return&nbsp;</em><code>-1</code><em>&nbsp;if it is not possible.</em></p>



<p>A subset is a group integers that appear in the array with no particular order.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [1,2,1,4], k = 2
<strong>Output:</strong> 4
<strong>Explanation:</strong> The optimal distribution of subsets is [1,2] and [1,4].
The incompatibility is (2-1) + (4-1) = 4.
Note that [1,1] and [2,4] would result in a smaller sum, but the first subset contains 2 equal elements.</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [6,3,8,1,3,1,2,2], k = 4
<strong>Output:</strong> 6
<strong>Explanation:</strong> The optimal distribution of subsets is [1,2], [2,3], [6,8], and [1,3].
The incompatibility is (2-1) + (3-2) + (8-6) + (3-1) = 6.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [5,3,3,6,3,3], k = 3
<strong>Output:</strong> -1
<strong>Explanation:</strong> It is impossible to distribute nums into 3 subsets where no two elements are equal in the same subset.
</pre>



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



<ul><li><code>1 &lt;= k &lt;= nums.length &lt;= 16</code></li><li><code>nums.length</code>&nbsp;is divisible by&nbsp;<code>k</code></li><li><code>1 &lt;= nums[i] &lt;= nums.length</code></li></ul>



<h2><strong>Solution: TSP</strong></h2>



<figure class="wp-block-image size-large"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/12/1681-ep374-1.png" alt="" class="wp-image-7781" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/12/1681-ep374-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/12/1681-ep374-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/12/1681-ep374-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/12/1681-ep374-2.png" alt="" class="wp-image-7782" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/12/1681-ep374-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/12/1681-ep374-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/12/1681-ep374-2-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></figure>



<p>dp[s][i] := min cost to distribute a set of numbers represented as a binary mask s, the last number in the set is the i-th number.</p>



<p>Init: <br>1.dp[*][*] = inf <br>2. dp[1 &lt;&lt;i][i] = 0, cost of selecting a single number is zero.<br><br>Transition: <br>1. dp[s | (1 &lt;&lt; j)][j] = dp[s][i] if s % (n / k) == 0, we start a new group, no extra cost.<br>2. dp[s | (1 &lt;&lt; j)][j] = dp[s][i] + nums[j] &#8211; nums[i] if nums[j] &gt; nums[i]. In the same group, we require the selected numbers are monotonically increasing. Each cost is nums[j] &#8211; nums[i].<br>e.g. 1, 3, 7, 20, cost is (3 &#8211; 1) + (7 &#8211; 3) + (20 &#8211; 7) = 20 &#8211; 1 = 19.</p>



<p>Ans: min(dp[(1 &lt;&lt; n) &#8211; 1])</p>



<p>Time complexity: O(2^n * n^2)<br>Space complexity: O(2^n * 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 minimumIncompatibility(vector&lt;int&gt;&amp; nums, int k) {
    const int n = nums.size(); 
    const int c = n / k;
    int dp[1 &lt;&lt; 16][16];
    memset(dp, 0x7f, sizeof(dp));
    for (int i = 0; i &lt; n; ++i) dp[1 &lt;&lt; i][i] = 0;
    for (int s = 0; s &lt; 1 &lt;&lt; n; ++s)
      for (int i = 0; i &lt; n; ++i) {
        if ((s &amp; (1 &lt;&lt; i)) == 0) continue;
        for (int j = 0; j &lt; n; ++j) {
          if ((s &amp; (1 &lt;&lt; j))) continue;
          const int t = s | (1 &lt;&lt; j);
          if (__builtin_popcount(s) % c == 0) {
            dp[t][j] = min(dp[t][j], dp[s][i]);
          } else if (nums[j] &gt; nums[i]) {           
            dp[t][j] = min(dp[t][j], 
                           dp[s][i] + nums[j] - nums[i]);            
          }
        }        
    }
    int ans = *min_element(begin(dp[(1 &lt;&lt; n) - 1]), 
                           end(dp[(1 &lt;&lt; n) - 1]));
    return ans &gt; 1e9 ? - 1 : ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1681-minimum-incompatibility/">花花酱 LeetCode 1681. Minimum Incompatibility</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-1681-minimum-incompatibility/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 943. Find the Shortest Superstring</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-943-find-the-shortest-superstring/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-943-find-the-shortest-superstring/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 18 Nov 2018 23:10:30 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[Hamiltonian path]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[NPC]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[TSP]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=4343</guid>

					<description><![CDATA[<p>Problem Given an array A of strings, find any&#160;smallest string that contains each string in&#160;A&#160;as a&#160;substring. We may assume that no string in&#160;A&#160;is substring of&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-943-find-the-shortest-superstring/">花花酱 LeetCode 943. Find the Shortest Superstring</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/u_Wc4jwrp3Q?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<h1><strong>Problem</strong></h1>
<p>Given an array A of strings, find any&nbsp;smallest string that contains each string in&nbsp;<code>A</code>&nbsp;as a&nbsp;substring.</p>
<p>We may assume that no string in&nbsp;<code>A</code>&nbsp;is substring of another string in&nbsp;<code>A</code>.</p>
<div>
<p><strong>Example 1:</strong></p>
<pre class="crayon:false"><strong>Input: </strong><span id="example-input-1-1">["alex","loves","leetcode"]</span>
<strong>Output: </strong><span id="example-output-1">"alexlovesleetcode"</span>
<strong>Explanation: </strong>All permutations of "alex","loves","leetcode" would also be accepted.
</pre>
<div>
<p><strong>Example 2:</strong></p>
<pre class="crayon:false"><strong>Input: </strong><span id="example-input-2-1">["catg","ctaagt","gcta","ttca","atgcatc"]</span>
<strong>Output: </strong><span id="example-output-2">"gctaagttcatgcatc"</span></pre>
</div>
</div>
<p><strong>Note:</strong></p>
<ol>
<li><code>1 &lt;= A.length &lt;= 12</code></li>
<li><code>1 &lt;= A[i].length &lt;= 20</code></li>
</ol>
<p><img class="alignnone size-full wp-image-4352" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/11/943-ep231.png" alt="" width="960" height="540"></p>
<h1><strong>Solution 1: Search +&nbsp;Pruning</strong></h1>
<p>Try all permutations. Pre-process the cost from word[i] to word[j] and store it in g[i][j].</p>
<p>Time complexity: O(n!)</p>
<p>Space complexity: O(n)</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua, running time: 692 ms
class Solution {
public:
  string shortestSuperstring(vector&lt;string&gt;&amp; A) {    
    const int n = A.size();
    g_ = vector&lt;vector&lt;int&gt;&gt;(n, vector&lt;int&gt;(n));
    for (int i = 0; i &lt; n; ++i)
      for (int j = 0; j &lt; n; ++j) {
        g_[i][j] = A[j].length();
        for (int k = 1; k &lt;= min(A[i].length(), A[j].length()); ++k)
          if (A[i].substr(A[i].size() - k) == A[j].substr(0, k))            
            g_[i][j] = A[j].length() - k;
      }
    vector&lt;int&gt; path(n);
    best_len_ = INT_MAX;
    dfs(A, 0, 0, 0, path);    
    string ans = A[best_path_[0]];
    for (int k = 1; k &lt; best_path_.size(); ++k) {
      int i = best_path_[k - 1];
      int j = best_path_[k];
      ans += A[j].substr(A[j].length() - g_[i][j]);
    }
    return ans;
  }
private:
  vector&lt;vector&lt;int&gt;&gt; g_;
  vector&lt;int&gt; best_path_;
  int best_len_;
  void dfs(const vector&lt;string&gt;&amp; A, int d, int used, int cur_len, vector&lt;int&gt;&amp; path) {
    if (cur_len &gt;= best_len_) return;
    if (d == A.size()) {
      best_len_ = cur_len;
      best_path_ = path;
      return;
    }
    
    for (int i = 0; i &lt; A.size(); ++i) {
      if (used &amp; (1 &lt;&lt; i)) continue;      
      path[d] = i;
      dfs(A,
          d + 1, 
          used | (1 &lt;&lt; i),
          d == 0 ? A[i].length() : cur_len + g_[path[d - 1]][i],
          path);
    }
  }
};</pre><p></div><h2 class="tabtitle">Java</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua, 439 ms, 35.8MB
class Solution {
  private int n;
  private int[][] g;
  private String[] a;
  private int best_len;
  private int[] path;
  private int[] best_path;
  
  private void dfs(int d, int used, int cur_len) {
    if (cur_len &gt;= best_len) return;
    if (d == n) {
      best_len = cur_len;
      best_path = path.clone();
      return;
    }
    
    for (int i = 0; i &lt; n; ++i) {
      if ((used &amp; (1 &lt;&lt; i)) != 0) continue;
      path[d] = i;
      dfs(d + 1, 
          used | (1 &lt;&lt; i), 
          d == 0 ? a[i].length() : cur_len + g[path[d - 1]][i]);
    }
  }
  
  public String shortestSuperstring(String[] A) {
    n = A.length;
    g = new int[n][n];
    a = A;
    for (int i = 0; i &lt; n; ++i)
      for (int j = 0; j &lt; n; ++j) {
        g[i][j] = A[j].length();
        for (int k = 1; k &lt;= Math.min(A[i].length(), A[j].length()); ++k)
          if (A[i].substring(A[i].length() - k).equals(A[j].substring(0, k)))
            g[i][j] = A[j].length() - k;        
      }
    
    path = new int[n];
    best_len = Integer.MAX_VALUE;
    
    dfs(0, 0, 0);
    
    String ans = A[best_path[0]];
    for (int k = 1; k &lt; n; ++k) {
      int i = best_path[k - 1];
      int j = best_path[k];
      ans += A[j].substring(A[j].length() - g[i][j]);      
    }
    return ans;
  }
}</pre><p></div></div></p>
<h1><strong>Solution 2: DP</strong></h1>
<p>g[i][j] is the cost of appending word[j] after word[i], or weight of edge[i][j].</p>
<p>We would like find the shortest path to visit each node from 0 to n &#8211; 1 once and only once this is called&nbsp;the Travelling sells man&#8217;s problem which is NP-Complete.</p>
<p>We can solve it with DP that uses exponential time.</p>
<p>dp[s][i] := min distance to visit nodes (represented as a binary state s) once and only once and the path ends with node i.</p>
<p>e.g. dp[7][1] is the min distance to visit nodes (0, 1, 2) and ends with node 1, the possible paths could be (0, 2, 1), (2, 0, 1).</p>
<p>Time complexity: O(n^2 * 2^n)</p>
<p>Space complexity: O(n * 2^n)</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua, running time: 20 ms
class Solution {
public:
  string shortestSuperstring(vector&lt;string&gt;&amp; A) {        
    const int n = A.size();
    vector&lt;vector&lt;int&gt;&gt; g(n, vector&lt;int&gt;(n));
    for (int i = 0; i &lt; n; ++i)
      for (int j = 0; j &lt; n; ++j) {
        g[i][j] = A[j].length();
        for (int k = 1; k &lt;= min(A[i].length(), A[j].length()); ++k)
          if (A[i].substr(A[i].size() - k) == A[j].substr(0, k)) 
            g[i][j] = A[j].length() - k;
      }
    
    vector&lt;vector&lt;int&gt;&gt; dp(1 &lt;&lt; n, vector&lt;int&gt;(n, INT_MAX / 2));
    vector&lt;vector&lt;int&gt;&gt; parent(1 &lt;&lt; n, vector&lt;int&gt;(n, -1));
    
    for (int i = 0; i &lt; n; ++i) dp[1 &lt;&lt; i][i] = A[i].length();
    
    for (int s = 1; s &lt; (1 &lt;&lt; n); ++s) {
      for (int j = 0; j &lt; n; ++j) {
        if (!(s &amp; (1 &lt;&lt; j))) continue;
        int ps = s &amp; ~(1 &lt;&lt; j);
        for (int i = 0; i &lt; n; ++i) {
          if (dp[ps][i] + g[i][j] &lt; dp[s][j]) {
            dp[s][j] = dp[ps][i] + g[i][j];
            parent[s][j] = i;
          }
        }
      }
    }
    
    auto it = min_element(begin(dp.back()), end(dp.back()));
    int j = it - begin(dp.back());
    int s = (1 &lt;&lt; n) - 1;
    string ans;
    while (s) {
      int i = parent[s][j];
      if (i &lt; 0) ans = A[j] + ans;
      else ans = A[j].substr(A[j].length() - g[i][j]) + ans;
      s &amp;= ~(1 &lt;&lt; j);
      j = i;
    }
    return ans;
  } 
};</pre><p></div></div></p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-943-find-the-shortest-superstring/">花花酱 LeetCode 943. Find the Shortest Superstring</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/searching/leetcode-943-find-the-shortest-superstring/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
