JulianJulianov

15. Longest Increasing Subsequence (LIS)

Feb 10th, 2020
289
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.08 KB | None | 0 0
  1. 15. Longest Increasing Subsequence (LIS)
  2. Read a list of integers and find the longest increasing subsequence (LIS). If several such exist, print the leftmost.
  3. Examples
  4. Input Output
  5. 1 1
  6. 7 3 5 8 -1 0 6 7 3 5 6 7
  7. 1 2 5 3 5 2 4 1 1 2 3 5
  8. 0 10 20 30 30 40 1 50 2 3 4 5 6 0 1 2 3 4 5 6
  9. 11 12 13 3 14 4 15 5 6 7 8 7 16 9 8 3 4 5 6 7 8 16
  10. 3 14 5 12 15 7 8 9 11 10 1 3 5 7 8 9 11
  11. Hints
  12. • Assume we have n numbers in an array nums[0…n-1].
  13. • Let len[p] holds the length of the longest increasing subsequence (LIS) ending at position p.
  14. • In a for loop, we shall calculate len[p] for p = 0 … n-1 as follows:
  15. o Let left is the leftmost position on the left of p (left < p), such that len[left] is the largest possible.
  16. o Then, len[p] = 1 + len[left]. If left does not exist, len[p] = 1.
  17. o Also, save prev[p] = left (we hold if prev[] the previous position, used to obtain the best length for position p).
  18. • Once the values for len[0…n-1] are calculated, restore the LIS starting from position p such that len[p] is maximal and go back and back through p = prev[p].
  19. • The table below illustrates these computations:
  20. index 0 1 2 3 4 5 6 7 8 9 10
  21. nums[] 3 14 5 12 15 7 8 9 11 10 1
  22. len[] 1 2 2 3 4 3 4 5 6 6 1
  23. prev[] -1 0 0 2 3 2 5 6 7 7 -1
  24. LIS {3} {3,14} {3,5} {3,5,12} {3,5,12,15} {3,5,7} {3,5,7,8} {3,5,7,8,9} {3,5,7,8,9,11} {3,5,7,8,9,10} {1}
  25.  
  26.  
  27. using System;
  28. using System.Linq;
  29.  
  30. namespace _05LongestIncreasingSubsequence_LIS_
  31. {
  32. class Program
  33. {
  34. static void Main(string[] args)
  35. {
  36. int[] sequence = Console.ReadLine()
  37. .Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
  38. .Select(x => int.Parse(x))
  39. .ToArray();
  40.  
  41. int[] lis;
  42. int[] len = new int[sequence.Length];
  43. int[] prev = new int[sequence.Length];
  44. int maxLength = 0;
  45. int lastIndex = -1;
  46.  
  47. // обхождам поредицата
  48. for (int i = 0; i < sequence.Length; i++)
  49. {
  50. // len && prev съответно = 1 && -1
  51. len[i] = 1;
  52. prev[i] = -1;
  53.  
  54. // обхождам поредицата и сравнявам за най-добра дължина на поредица
  55. // if i == j -> цикъл j няма да се изпълни
  56. for (int j = 0; j < i; j++)
  57. {
  58. // ако текущата стойност j/в ляво/ е по-малка от i/в дясно/
  59. // && текущия брой елементи j >= броя елементи на i -> броя на елементите /поредицата/ ще нараства
  60. if (sequence[j] < sequence[i] && len[j] >= len[i])
  61. {
  62. len[i] = 1 + len[j];
  63. prev[i] = j; // запазваме индекса на най добрия елемент от поредицата
  64. }
  65. }
  66. // запазвам максималния брой елементи
  67. if (len[i] > maxLength)
  68. {
  69. maxLength = len[i];
  70. lastIndex = i;
  71. }
  72. }
  73. lis = new int[maxLength];
  74. for (int i = 0; i < maxLength; i++)
  75. {
  76. lis[i] = sequence[lastIndex];
  77. lastIndex = prev[lastIndex];
  78. }
  79. Array.Reverse(lis);
  80. Console.WriteLine(string.Join(" ", lis));
  81. }
  82. }
  83. }
Advertisement
Add Comment
Please, Sign In to add comment