{"id":25344,"date":"2017-10-15T17:07:52","date_gmt":"2017-10-15T11:37:52","guid":{"rendered":"https:\/\/www.wikitechy.com\/technology\/?p=25344"},"modified":"2017-10-15T17:07:52","modified_gmt":"2017-10-15T11:37:52","slug":"c-programming-longest-increasing-subsequence","status":"publish","type":"post","link":"https:\/\/www.wikitechy.com\/technology\/c-programming-longest-increasing-subsequence\/","title":{"rendered":"C++ Programming &#8211; Longest Increasing Subsequence"},"content":{"rendered":"<p>We have discussed Overlapping Subproblems and Optimal Substructure properties in Set 1 and Set 2 respectively.<span id=\"more-12832\"><\/span><\/p>\n<p>Let us discuss Longest Increasing Subsequence (LIS) problem as an example problem that can be solved using Dynamic Programming.<br \/>\nThe Longest Increasing Subsequence (LIS) problem is to find the length of the longest subsequence of a given sequence such that all elements of the subsequence are sorted in increasing order. For example, the length of LIS for {10, 22, 9, 33, 21, 50, 41, 60, 80} is 6 and LIS is {10, 22, 33, 50, 60, 80}<\/p>\n<p><img fetchpriority=\"high\" decoding=\"async\" class=\"aligncenter size-full wp-image-25327\" src=\"https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/05\/Longest-Increasing-Subsequence.png\" alt=\"Longest-Increasing-Subsequence\" width=\"779\" height=\"89\" srcset=\"https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/05\/Longest-Increasing-Subsequence.png 779w, https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/05\/Longest-Increasing-Subsequence-300x34.png 300w, https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/05\/Longest-Increasing-Subsequence-768x88.png 768w\" sizes=\"(max-width: 779px) 100vw, 779px\" \/><\/p>\n<p>More Examples:<\/p>\n<pre>Input  : arr[] = {3, 10, 2, 1, 20}\r\nOutput : Length of LIS = 3\r\nThe longest increasing subsequence is 3, 10, 20\r\n\r\nInput  : arr[] = {3, 2}\r\nOutput : Length of LIS = 1\r\nThe longest increasing subsequences are {3} and {2}\r\n\r\nInput : arr[] = {50, 3, 10, 7, 40, 80}\r\nOutput : Length of LIS = 4\r\nThe longest increasing subsequence is {3, 7, 40, 80}<\/pre>\n[ad type=&#8221;banner&#8221;]\n<p><strong>Optimal Substructure:<\/strong><br \/>\nLet arr[0..n-1] be the input array and L(i) be the length of the LIS ending at index i such that arr[i] is the last element of the LIS.<br \/>\nThen, L(i) can be recursively written as:<br \/>\nL(i) = 1 + max( L(j) ) where 0 &lt; j &lt; i and arr[j] &lt; arr[i]; or<br \/>\nL(i) = 1, if no such j exists.<br \/>\nTo find the LIS for a given array, we need to return max(L(i)) where 0 &lt; i &lt; n.<br \/>\nThus, we see the LIS problem satisfies the optimal substructure property as the main problem can be solved using solutions to subproblems.<\/p>\n<p>Following is a simple recursive implementation of the LIS problem. It follows the recursive structure discussed above.<\/p>\n<p><strong>C++ Programming<\/strong><\/p>\n<div class=\"code-embed-wrapper\"> <div class=\"code-embed-infos\"> <span class=\"code-embed-name\">c++<\/span> <\/div> <pre class=\"language-cpp code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-cpp code-embed-code\">\/\/ A naive C\/C++ based recursive implementation of LIS problem<br\/>#include&lt;stdio.h&gt;<br\/>#include&lt;stdlib.h&gt;<br\/> <br\/>\/\/ Recursive implementation for calculating the LIS<br\/>int _lis(int arr[], int n, int *max_lis_length)<br\/>{<br\/>    \/\/ Base case<br\/>    if (n == 1)<br\/>        return 1;<br\/> <br\/>    int current_lis_length = 1;<br\/>    for (int i=0; i&lt;n-1; i++)<br\/>    {<br\/>        \/\/ Recursively calculate the length of the LIS<br\/>        \/\/ ending at arr[i]<br\/>        int subproblem_lis_length = _lis(arr, i, max_lis_length);<br\/> <br\/>        \/\/ Check if appending arr[n-1] to the LIS<br\/>        \/\/ ending at arr[i] gives us an LIS ending at<br\/>        \/\/ arr[n-1] which is longer than the previously<br\/>        \/\/ calculated LIS ending at arr[n-1] <br\/>        if (arr[i] &lt; arr[n-1] &amp;&amp;<br\/>            current_lis_length &lt; (1+subproblem_lis_length))<br\/>            current_lis_length = 1+subproblem_lis_length;<br\/>    }<br\/> <br\/>    \/\/ Check if currently calculated LIS ending at<br\/>    \/\/ arr[n-1] is longer than the previously calculated<br\/>    \/\/ LIS and update max_lis_length accordingly <br\/>    if (*max_lis_length &lt; current_lis_length)<br\/>        *max_lis_length = current_lis_length;<br\/> <br\/>    return current_lis_length;<br\/>}<br\/> <br\/>\/\/ The wrapper function for _lis()<br\/>int lis(int arr[], int n)<br\/>{<br\/>    int max_lis_length = 1; \/\/ stores the final LIS<br\/> <br\/>    \/\/ max_lis_length is passed as a reference below <br\/>    \/\/ so that it can maintain its value<br\/>    \/\/ between the recursive calls <br\/>    _lis( arr, n, &amp;max_lis_length );<br\/> <br\/>    return max_lis_length;<br\/>}<br\/> <br\/>\/\/ Driver program to test the functions above<br\/>int main()<br\/>{<br\/>    int arr[] = {10, 22, 9, 33, 21, 50, 41, 60};<br\/>    int n = sizeof(arr)\/sizeof(arr[0]);<br\/>    printf(&quot;Length of LIS is %d\\n&quot;, lis( arr, n ));<br\/>    return 0;<br\/>}<\/code><\/pre> <\/div>\n<p><strong>Output :<\/strong><\/p>\n<pre>Length of LIS is 5<\/pre>\n<p><strong>Overlapping Subproblems :<\/strong><br \/>\nConsidering the above implementation, following is recursion tree for an array of size 4. lis(n) gives us the length of LIS for arr[].<\/p>\n<pre>              lis(4)\r\n        \/        |     \\\r\n      lis(3)    lis(2)   lis(1)\r\n     \/   \\        \/\r\n   lis(2) lis(1) lis(1)\r\n   \/\r\nlis(1)\r\n<\/pre>\n<p>We can see that there are many subproblems which are solved again and again. So this problem has Overlapping Substructure property and recomputation of same subproblems can be avoided by either using Memoization or Tabulation. Following is a tabluated implementation for the LIS problem.<\/p>\n[ad type=&#8221;banner&#8221;]\n<p><strong>C++ Programming<\/strong><\/p>\n<div class=\"code-embed-wrapper\"> <div class=\"code-embed-infos\"> <span class=\"code-embed-name\">c++<\/span> <\/div> <pre class=\"language-cpp code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-cpp code-embed-code\">\/* Dynamic Programming C\/C++ implementation of LIS problem *\/<br\/>#include&lt;stdio.h&gt;<br\/>#include&lt;stdlib.h&gt;<br\/> <br\/>\/* lis() returns the length of the longest increasing<br\/>  subsequence in arr[] of size n *\/<br\/>int lis( int arr[], int n )<br\/>{<br\/>    int *lis, i, j, max = 0;<br\/>    lis = (int*) malloc ( sizeof( int ) * n );<br\/> <br\/>    \/* Initialize LIS values for all indexes *\/<br\/>    for (i = 0; i &lt; n; i++ )<br\/>        lis[i] = 1;<br\/> <br\/>    \/* Compute optimized LIS values in bottom up manner *\/<br\/>    for (i = 1; i &lt; n; i++ )<br\/>        for (j = 0; j &lt; i; j++ ) <br\/>            if ( arr[i] &gt; arr[j] &amp;&amp; lis[i] &lt; lis[j] + 1)<br\/>                lis[i] = lis[j] + 1;<br\/> <br\/>    \/* Pick maximum of all LIS values *\/<br\/>    for (i = 0; i &lt; n; i++ )<br\/>        if (max &lt; lis[i])<br\/>            max = lis[i];<br\/> <br\/>    \/* Free memory to avoid memory leak *\/<br\/>    free(lis);<br\/> <br\/>    return max;<br\/>}<br\/> <br\/>\/* Driver program to test above function *\/<br\/>int main()<br\/>{<br\/>    int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 };<br\/>    int n = sizeof(arr)\/sizeof(arr[0]);<br\/>    printf(&quot;Length of lis is %d\\n&quot;, lis( arr, n ) );<br\/>    return 0;<br\/>}<\/code><\/pre> <\/div>\n<p><strong>Output :<\/strong><\/p>\n<pre>Length of lis is 5<\/pre>\n<p>Note that the time complexity of the above Dynamic Programming (DP) solution is O(n^2) and there is a O(nLogn) solution for the LIS problem.<\/p>\n[ad type=&#8221;banner&#8221;]\n","protected":false},"excerpt":{"rendered":"<p>C++ Programming &#8211; Longest Increasing Subsequence &#8211; Dynamic Programming The LIS problem is to find the length of the longest subsequence of a given sequence<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[83515,1,70145],"tags":[72847,72842,72983,70483,72841,72848,72840,72849,72846,72843,72854,72844,72850,72839,72977,72979,72984,72978,72975,72981,72980,72976,72852,72855,72853,72851],"class_list":["post-25344","post","type-post","status-publish","format-standard","hentry","category-c-programming-3","category-coding","category-dynamic-programming","tag-concept-of-dynamic-programming","tag-define-dynamic-programming","tag-definition-of-dynamic-programming-in-c","tag-dynamic-programming","tag-dynamic-programming-c","tag-dynamic-programming-code-generation-algorithm","tag-dynamic-programming-definition","tag-dynamic-programming-in-c","tag-dynamic-programming-in-data-structure","tag-dynamic-programming-problems","tag-dynamic-programming-set-1","tag-dynamic-programming-software","tag-explain-dynamic-programming","tag-how-to-solve-dynamic-programming-problems","tag-longest-increasing-subsequence-c","tag-longest-increasing-subsequence-code","tag-longest-increasing-subsequence-in-c","tag-longest-increasing-subsequence-java","tag-longest-increasing-subsequence-nlogn","tag-longest-increasing-subsequence-recursive","tag-longest-increasing-subsequence-youtube","tag-longest-increasing-subsequences","tag-problems-on-dynamic-programming","tag-simple-dynamic-programming-example","tag-types-of-dynamic-programming","tag-youtube-dynamic-programming"],"_links":{"self":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/25344","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/comments?post=25344"}],"version-history":[{"count":0,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/25344\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/media?parent=25344"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/categories?post=25344"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/tags?post=25344"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}