using System; using System.Collections; using System.Collections.Generic; using System.Linq; public static class LIS { public static IEnumerable FindRec(IList values, IComparer comparer = null) => values == null ? throw new ArgumentNullException() : FindRecImpl(values, Sequence.Empty, 0, comparer ?? Comparer.Default).Reverse(); private static Sequence FindRecImpl(IList values, Sequence current, int index, IComparer comparer) { if (index == values.Count) return current; if (current.Length > 0 && comparer.Compare(values[index], current.Value) <= 0) return FindRecImpl(values, current, index + 1, comparer); return Max( FindRecImpl(values, current, index + 1, comparer), FindRecImpl(values, current + values[index], index + 1, comparer) ); } private static Sequence Max(Sequence a, Sequence b) => a.Length < b.Length ? b : a; class Sequence : IEnumerable { public static readonly Sequence Empty = new Sequence(default(T), null); public Sequence(T value, Sequence tail) { Value = value; Tail = tail; Length = tail == null ? 0 : tail.Length + 1; } public T Value { get; } public Sequence Tail { get; } public int Length { get; } public static Sequence operator +(Sequence s, T value) => new Sequence(value, s); public IEnumerator GetEnumerator() { for (var s = this; s.Length > 0; s = s.Tail) yield return s.Value; } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } }