猿问

如何利用动态规划确定最长增长子序列?

如何利用动态规划确定最长增长子序列?

我有一组整数。我想找到最长增长子序列使用动态规划。



不负相思意
浏览 625回答 3
3回答

蓝山帝景

Petar Minchev的解释帮助我澄清了问题,但是我很难解析所有的东西,所以我使用了描述性很强的变量名和大量的注释来实现Python。我做了一个简单的递归解,O(n^2)解和O(N Log N)解。我希望它能帮助清理算法!递归解def&nbsp;recursive_solution(remaining_sequence,&nbsp;bigger_than=None): &nbsp;&nbsp;&nbsp;&nbsp;"""Finds&nbsp;the&nbsp;longest&nbsp;increasing&nbsp;subsequence&nbsp;of&nbsp;remaining_sequence&nbsp;that&nbsp;is&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;bigger&nbsp;than&nbsp;bigger_than&nbsp;and&nbsp;returns&nbsp;it.&nbsp;&nbsp;This&nbsp;solution&nbsp;is&nbsp;O(2^n).""" &nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Base&nbsp;case:&nbsp;nothing&nbsp;is&nbsp;remaining.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;len(remaining_sequence)&nbsp;==&nbsp;0: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;remaining_sequence&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Recursive&nbsp;case&nbsp;1:&nbsp;exclude&nbsp;the&nbsp;current&nbsp;element&nbsp;and&nbsp;process&nbsp;the&nbsp;remaining.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;best_sequence&nbsp;=&nbsp;recursive_solution(remaining_sequence[1:],&nbsp;bigger_than) &nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Recursive&nbsp;case&nbsp;2:&nbsp;include&nbsp;the&nbsp;current&nbsp;element&nbsp;if&nbsp;it's&nbsp;big&nbsp;enough.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;first&nbsp;=&nbsp;remaining_sequence[0] &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(first&nbsp;>&nbsp;bigger_than)&nbsp;or&nbsp;(bigger_than&nbsp;is&nbsp;None): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sequence_with&nbsp;=&nbsp;[first]&nbsp;+&nbsp;recursive_solution(remaining_sequence[1:],&nbsp;first) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Choose&nbsp;whichever&nbsp;of&nbsp;case&nbsp;1&nbsp;and&nbsp;case&nbsp;2&nbsp;were&nbsp;longer.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;len(sequence_with)&nbsp;>=&nbsp;len(best_sequence): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;best_sequence&nbsp;=&nbsp;sequence_with&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;best_sequenceO(n^2)动态规划解def&nbsp;dynamic_programming_solution(sequence): &nbsp;&nbsp;&nbsp;&nbsp;"""Finds&nbsp;the&nbsp;longest&nbsp;increasing&nbsp;subsequence&nbsp;in&nbsp;sequence&nbsp;using&nbsp;dynamic&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;programming.&nbsp;&nbsp;This&nbsp;solution&nbsp;is&nbsp;O(n^2).""" &nbsp;&nbsp;&nbsp;&nbsp;longest_subsequence_ending_with&nbsp;=&nbsp;[] &nbsp;&nbsp;&nbsp;&nbsp;backreference_for_subsequence_ending_with&nbsp;=&nbsp;[] &nbsp;&nbsp;&nbsp;&nbsp;current_best_end&nbsp;=&nbsp;0 &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;curr_elem&nbsp;in&nbsp;range(len(sequence)): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;It's&nbsp;always&nbsp;possible&nbsp;to&nbsp;have&nbsp;a&nbsp;subsequence&nbsp;of&nbsp;length&nbsp;1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;longest_subsequence_ending_with.append(1) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;If&nbsp;a&nbsp;subsequence&nbsp;is&nbsp;length&nbsp;1,&nbsp;it&nbsp;doesn't&nbsp;have&nbsp;a&nbsp;backreference.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;backreference_for_subsequence_ending_with.append(None) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;prev_elem&nbsp;in&nbsp;range(curr_elem): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;subsequence_length_through_prev&nbsp;=&nbsp;(longest_subsequence_ending_with[prev_elem]&nbsp;+&nbsp;1) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;If&nbsp;the&nbsp;prev_elem&nbsp;is&nbsp;smaller&nbsp;than&nbsp;the&nbsp;current&nbsp;elem&nbsp;(so&nbsp;it's&nbsp;increasing)&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;And&nbsp;if&nbsp;the&nbsp;longest&nbsp;subsequence&nbsp;from&nbsp;prev_elem&nbsp;would&nbsp;yield&nbsp;a&nbsp;better&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;subsequence&nbsp;for&nbsp;curr_elem.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;((sequence[prev_elem]&nbsp;<&nbsp;sequence[curr_elem])&nbsp;and &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(subsequence_length_through_prev&nbsp;> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;longest_subsequence_ending_with[curr_elem])): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Set&nbsp;the&nbsp;candidate&nbsp;best&nbsp;subsequence&nbsp;at&nbsp;curr_elem&nbsp;to&nbsp;go&nbsp;through&nbsp;prev.&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;longest_subsequence_ending_with[curr_elem]&nbsp;=&nbsp;(subsequence_length_through_prev) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;backreference_for_subsequence_ending_with[curr_elem]&nbsp;=&nbsp;prev_elem&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;If&nbsp;the&nbsp;new&nbsp;end&nbsp;is&nbsp;the&nbsp;best,&nbsp;update&nbsp;the&nbsp;best.&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(longest_subsequence_ending_with[curr_elem]&nbsp;> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;longest_subsequence_ending_with[current_best_end]): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current_best_end&nbsp;=&nbsp;curr_elem&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Output&nbsp;the&nbsp;overall&nbsp;best&nbsp;by&nbsp;following&nbsp;the&nbsp;backreferences.&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;best_subsequence&nbsp;=&nbsp;[] &nbsp;&nbsp;&nbsp;&nbsp;current_backreference&nbsp;=&nbsp;current_best_end&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;current_backreference&nbsp;is&nbsp;not&nbsp;None: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;best_subsequence.append(sequence[current_backreference]) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current_backreference&nbsp;=&nbsp;(backreference_for_subsequence_ending_with[current_backreference]) &nbsp;&nbsp;&nbsp;&nbsp;best_subsequence.reverse() &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;best_subsequenceO(N Log N)动态规划解def&nbsp;find_smallest_elem_as_big_as(sequence,&nbsp;subsequence,&nbsp;elem): &nbsp;&nbsp;&nbsp;&nbsp;"""Returns&nbsp;the&nbsp;index&nbsp;of&nbsp;the&nbsp;smallest&nbsp;element&nbsp;in&nbsp;subsequence&nbsp;as&nbsp;big&nbsp;as&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;sequence[elem].&nbsp;&nbsp;sequence[elem]&nbsp;must&nbsp;not&nbsp;be&nbsp;larger&nbsp;than&nbsp;every&nbsp;element&nbsp;in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;subsequence.&nbsp;&nbsp;The&nbsp;elements&nbsp;in&nbsp;subsequence&nbsp;are&nbsp;indices&nbsp;in&nbsp;sequence.&nbsp;&nbsp;Uses&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;binary&nbsp;search.""" &nbsp;&nbsp;&nbsp;&nbsp;low&nbsp;=&nbsp;0 &nbsp;&nbsp;&nbsp;&nbsp;high&nbsp;=&nbsp;len(subsequence)&nbsp;-&nbsp;1 &nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;high&nbsp;>&nbsp;low: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mid&nbsp;=&nbsp;(high&nbsp;+&nbsp;low)&nbsp;/&nbsp;2 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;If&nbsp;the&nbsp;current&nbsp;element&nbsp;is&nbsp;not&nbsp;as&nbsp;big&nbsp;as&nbsp;elem,&nbsp;throw&nbsp;out&nbsp;the&nbsp;low&nbsp;half&nbsp;of&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;sequence.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;sequence[subsequence[mid]]&nbsp;<&nbsp;sequence[elem]: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;low&nbsp;=&nbsp;mid&nbsp;+&nbsp;1 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;If&nbsp;the&nbsp;current&nbsp;element&nbsp;is&nbsp;as&nbsp;big&nbsp;as&nbsp;elem,&nbsp;throw&nbsp;out&nbsp;everything&nbsp;bigger,&nbsp;but&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;keep&nbsp;the&nbsp;current&nbsp;element.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;high&nbsp;=&nbsp;mid&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;highdef&nbsp;optimized_dynamic_programming_solution(sequence): &nbsp;&nbsp;&nbsp;&nbsp;"""Finds&nbsp;the&nbsp;longest&nbsp;increasing&nbsp;subsequence&nbsp;in&nbsp;sequence&nbsp;using&nbsp;dynamic&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;programming&nbsp;and&nbsp;binary&nbsp;search&nbsp;(per&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;http://en.wikipedia.org/wiki/Longest_increasing_subsequence).&nbsp;&nbsp;This&nbsp;solution&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;is&nbsp;O(n&nbsp;log&nbsp;n).""" &nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Both&nbsp;of&nbsp;these&nbsp;lists&nbsp;hold&nbsp;the&nbsp;indices&nbsp;of&nbsp;elements&nbsp;in&nbsp;sequence&nbsp;and&nbsp;not&nbsp;the&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;elements&nbsp;themselves.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;This&nbsp;list&nbsp;will&nbsp;always&nbsp;be&nbsp;sorted.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;smallest_end_to_subsequence_of_length&nbsp;=&nbsp;[] &nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;This&nbsp;array&nbsp;goes&nbsp;along&nbsp;with&nbsp;sequence&nbsp;(not&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;smallest_end_to_subsequence_of_length).&nbsp;&nbsp;Following&nbsp;the&nbsp;corresponding&nbsp;element&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;in&nbsp;this&nbsp;array&nbsp;repeatedly&nbsp;will&nbsp;generate&nbsp;the&nbsp;desired&nbsp;subsequence.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;parent&nbsp;=&nbsp;[None&nbsp;for&nbsp;_&nbsp;in&nbsp;sequence] &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;elem&nbsp;in&nbsp;range(len(sequence)): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;We're&nbsp;iterating&nbsp;through&nbsp;sequence&nbsp;in&nbsp;order,&nbsp;so&nbsp;if&nbsp;elem&nbsp;is&nbsp;bigger&nbsp;than&nbsp;the&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;end&nbsp;of&nbsp;longest&nbsp;current&nbsp;subsequence,&nbsp;we&nbsp;have&nbsp;a&nbsp;new&nbsp;longest&nbsp;increasing&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;subsequence.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(len(smallest_end_to_subsequence_of_length)&nbsp;==&nbsp;0&nbsp;or &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sequence[elem]&nbsp;>&nbsp;sequence[smallest_end_to_subsequence_of_length[-1]]): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;If&nbsp;we&nbsp;are&nbsp;adding&nbsp;the&nbsp;first&nbsp;element,&nbsp;it&nbsp;has&nbsp;no&nbsp;parent.&nbsp;&nbsp;Otherwise,&nbsp;we&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;need&nbsp;to&nbsp;update&nbsp;the&nbsp;parent&nbsp;to&nbsp;be&nbsp;the&nbsp;previous&nbsp;biggest&nbsp;element.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;len(smallest_end_to_subsequence_of_length)&nbsp;>&nbsp;0: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parent[elem]&nbsp;=&nbsp;smallest_end_to_subsequence_of_length[-1] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;smallest_end_to_subsequence_of_length.append(elem) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;If&nbsp;we&nbsp;can't&nbsp;make&nbsp;a&nbsp;longer&nbsp;subsequence,&nbsp;we&nbsp;might&nbsp;be&nbsp;able&nbsp;to&nbsp;make&nbsp;a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;subsequence&nbsp;of&nbsp;equal&nbsp;size&nbsp;to&nbsp;one&nbsp;of&nbsp;our&nbsp;earlier&nbsp;subsequences&nbsp;with&nbsp;a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;smaller&nbsp;ending&nbsp;number&nbsp;(which&nbsp;makes&nbsp;it&nbsp;easier&nbsp;to&nbsp;find&nbsp;a&nbsp;later&nbsp;number&nbsp;that&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;is&nbsp;increasing).&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Thus,&nbsp;we&nbsp;look&nbsp;for&nbsp;the&nbsp;smallest&nbsp;element&nbsp;in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;smallest_end_to_subsequence_of_length&nbsp;that&nbsp;is&nbsp;at&nbsp;least&nbsp;as&nbsp;big&nbsp;as&nbsp;elem&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;and&nbsp;replace&nbsp;it&nbsp;with&nbsp;elem.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;This&nbsp;preserves&nbsp;correctness&nbsp;because&nbsp;if&nbsp;there&nbsp;is&nbsp;a&nbsp;subsequence&nbsp;of&nbsp;length&nbsp;n&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;that&nbsp;ends&nbsp;with&nbsp;a&nbsp;number&nbsp;smaller&nbsp;than&nbsp;elem,&nbsp;we&nbsp;could&nbsp;add&nbsp;elem&nbsp;on&nbsp;to&nbsp;the&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;end&nbsp;of&nbsp;that&nbsp;subsequence&nbsp;to&nbsp;get&nbsp;a&nbsp;subsequence&nbsp;of&nbsp;length&nbsp;n+1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;location_to_replace&nbsp;=&nbsp;find_smallest_elem_as_big_as(sequence,&nbsp;smallest_end_to_subsequence_of_length,&nbsp;elem) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;smallest_end_to_subsequence_of_length[location_to_replace]&nbsp;=&nbsp;elem&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;If&nbsp;we're&nbsp;replacing&nbsp;the&nbsp;first&nbsp;element,&nbsp;we&nbsp;don't&nbsp;need&nbsp;to&nbsp;update&nbsp;its&nbsp;parent&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;because&nbsp;a&nbsp;subsequence&nbsp;of&nbsp;length&nbsp;1&nbsp;has&nbsp;no&nbsp;parent.&nbsp;&nbsp;Otherwise,&nbsp;its&nbsp;parent&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;is&nbsp;the&nbsp;subsequence&nbsp;one&nbsp;shorter,&nbsp;which&nbsp;we&nbsp;just&nbsp;added&nbsp;onto.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;location_to_replace&nbsp;!=&nbsp;0: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parent[elem]&nbsp;=&nbsp;(smallest_end_to_subsequence_of_length[location_to_replace&nbsp;-&nbsp;1]) &nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Generate&nbsp;the&nbsp;longest&nbsp;increasing&nbsp;subsequence&nbsp;by&nbsp;backtracking&nbsp;through&nbsp;parent.&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;curr_parent&nbsp;=&nbsp;smallest_end_to_subsequence_of_length[-1] &nbsp;&nbsp;&nbsp;&nbsp;longest_increasing_subsequence&nbsp;=&nbsp;[] &nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;curr_parent&nbsp;is&nbsp;not&nbsp;None: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;longest_increasing_subsequence.append(sequence[curr_parent]) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curr_parent&nbsp;=&nbsp;parent[curr_parent] &nbsp;&nbsp;&nbsp;&nbsp;longest_increasing_subsequence.reverse() &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;longest_increasing_subsequence

慕少森

谈到dp解决方案,我感到惊讶的是,没有人提到lis可以简化为LCS..您所需要做的就是对原始序列的副本进行排序,删除所有副本并对它们执行LCS。在伪码中是:def&nbsp;LIS(S): &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;=&nbsp;sort(S) &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;=&nbsp;removeDuplicates(T) &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;LCS(S,&nbsp;T)并以Go语言编写了完整的实现程序。如果不需要重构解决方案,则不需要维护整个n^2 dp矩阵。func&nbsp;lcs(arr1&nbsp;[]int)&nbsp;int&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;arr2&nbsp;:=&nbsp;make([]int,&nbsp;len(arr1)) &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;i,&nbsp;v&nbsp;:=&nbsp;range&nbsp;arr1&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arr2[i]&nbsp;=&nbsp;v &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;sort.Ints(arr1) &nbsp;&nbsp;&nbsp;&nbsp;arr3&nbsp;:=&nbsp;[]int{} &nbsp;&nbsp;&nbsp;&nbsp;prev&nbsp;:=&nbsp;arr1[0]&nbsp;-&nbsp;1 &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;_,&nbsp;v&nbsp;:=&nbsp;range&nbsp;arr1&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;v&nbsp;!=&nbsp;prev&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev&nbsp;=&nbsp;v &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arr3&nbsp;=&nbsp;append(arr3,&nbsp;v) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;n1,&nbsp;n2&nbsp;:=&nbsp;len(arr1),&nbsp;len(arr3) &nbsp;&nbsp;&nbsp;&nbsp;M&nbsp;:=&nbsp;make([][]int,&nbsp;n2&nbsp;+&nbsp;1) &nbsp;&nbsp;&nbsp;&nbsp;e&nbsp;:=&nbsp;make([]int,&nbsp;(n1&nbsp;+&nbsp;1)&nbsp;*&nbsp;(n2&nbsp;+&nbsp;1)) &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;i&nbsp;:=&nbsp;range&nbsp;M&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;M[i]&nbsp;=&nbsp;e[i&nbsp;*&nbsp;(n1&nbsp;+&nbsp;1):(i&nbsp;+&nbsp;1)&nbsp;*&nbsp;(n1&nbsp;+&nbsp;1)] &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;i&nbsp;:=&nbsp;1;&nbsp;i&nbsp;<=&nbsp;n2;&nbsp;i++&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;j&nbsp;:=&nbsp;1;&nbsp;j&nbsp;<=&nbsp;n1;&nbsp;j++&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;arr2[j&nbsp;-&nbsp;1]&nbsp;==&nbsp;arr3[i&nbsp;-&nbsp;1]&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;M[i][j]&nbsp;=&nbsp;M[i&nbsp;-&nbsp;1][j&nbsp;-&nbsp;1]&nbsp;+&nbsp;1 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;if&nbsp;M[i&nbsp;-&nbsp;1][j]&nbsp;>&nbsp;M[i][j&nbsp;-&nbsp;1]&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;M[i][j]&nbsp;=&nbsp;M[i&nbsp;-&nbsp;1][j] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;M[i][j]&nbsp;=&nbsp;M[i][j&nbsp;-&nbsp;1] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;M[n2][n1] }
随时随地看视频慕课网APP
我要回答