Tutaj skoro masz tylko tyle liczb, to nie musisz robić żadnego dp, a mianowicie:
Masz 3 przypadki:
L[i] i-ta liczba z wyjścia
- jeśli L[i] = 0, to wyn = max(wyn,1), bo nie podbijesz tej jedynki nigdzie w lewo,bo nie możesz np 0, 0, albo -1, 0.
- jeśli L[i] = 1, to jeśli wcześniej było jakieś zero(musisz mieć flagę bool czy_bylo_zero) i jeśli było, to wyn = max(wyn,2), a jak nie to wyn = max(wyn,1), bo nigdy na lewo nie podbijesz tej jedynki.
- jeśli L[i] = 2, to musisz mieć zmienną max_wyn_dla_jedynki, na początku -1, i jeśli max_wyn_dla_jedynki = -1 (nie było wcześniej jedynki, jeśli masz L[i] = 1, to max_wyn_jedynki = max(max_wyn_jedynki, to co sprawdzaliśmy, gdy L[i] = 1), to sprawdzasz czy było wczesniej zero. Jak było, to wyn = max(wyn,2), jak nie to wyn = max(wyn,1). A natomiast, jeśli max_wyn_dla_jedynki != -1, to wyn = max(wyn, max_wyn_dla_jedynki+1)
I dostajesz rozwiąnie O(N), i pamięć O(1)
I na koniec zwracasz wyn.
Ciekawszy jest problem szukania najdłuższego podciągu rosnącego, jak liczby są dowolne. Wtedy robisz faktycznie dp.
dp[i] = max z wszystkich dp wcześniejszych, gdzie L[i] > L[j], taki naiwny algorytm ma O(N^2), a można zrobić w O(N lg N), korzystając z drzewa przedziałowego przedział-punkt, gdzie klucze to wartości, a wyniki w drzewie, to max dp dla danej wartości. Popatrz sobie na zadanie Sponsor z 1 OI, jest też na forum.
https://szkopul.edu.pl/problemset/problem/E3eS485F0Qmr6RLduybh_e5b/site/?key=statement