2684 - Hard ssc

De la Universitas MediaWiki
Versiunea pentru tipărire nu mai este suportată și poate avea erori de randare. Vă rugăm să vă actualizați bookmarkurile browserului și să folosiți funcția implicită de tipărire a browserului.

Se dă un șir de n numere naturale. Șirul poate fi partiționat în mai multe moduri într-un număr de subșiruri strict crescătoare. De exemplu, șirul 4 6 2 5 8 1 3 7 poate fi partiționat astfel: 4 6 8 (primul subșir), 2 5 7 (al doilea) și 1 3 (al treilea). O altă modalitate este formând patru subșiruri: 4 5 7, 6 8, 2 3 și 1.

Cerinţa

Să se determine numărul minim de subșiruri strict crescătoare în care se poate partiționa șirul.

Date de intrare

Programul citește de la tastatură numărul n, iar apoi șirul de n numere naturale, separate prin spații.

Date de ieșire

Programul va afișa pe ecran numărul minim de subșiruri strict crescătoare în care se poate partiționa șirul.

Restricţii şi precizări

  • 1 ⩽ n ⩽ 100.000
  • cele n numere citite vor fi mai mici decât 100.000
  • Un subșir se obține dintr-un șir prin eliminarea a zero, unul, sau mai multe elemente.

Exemplu 1

Intrare
8
4 6 2 5 8 1 3 7
Iesire
Datele de intrare corespund restrictiilor impuse
3


Exemplu 2

Intrare
100002
12 12
Iesire
Datele de intrare nu corespund restrictiilor impuse


Rezolvare

from bisect import bisect_left


def numar_minim_subsecvente(n, sir):
    # Calculează numărul minim de subșiruri strict crescătoare în care se poate partiționa șirul.

    subsecvente = [0] * n
    lungime = 1

    # Primul element al sirului este întotdeauna o subsecvență în sine
    subsecvente[0] = sir[0]

    for i in range(1, n):
        # Dacă elementul curent este mai mare decât ultimul element al subsecvenței curente,
        # îl adăugăm la sfârșitul subsecvenței și creștem lungimea acesteia
        if sir[i] > subsecvente[lungime - 1]:
            subsecvente[lungime] = sir[i]
            lungime += 1
        else:
            # Dacă elementul curent este mai mic sau egal cu ultimul element al subsecvenței curente,
            # înlocuim cel mai mare element care este mai mic sau egal cu elementul curent
            j = bisect_left(subsecvente, sir[i], 0, lungime)
            subsecvente[j] = sir[i]

    return lungime


def main():
    n = int(input().strip())
    sir = list(map(int, input().split()))

    # Verifică dacă datele de intrare respectă restricțiile
    if not (1 <= n <= 100000 and all(0 <= x < 100000 for x in sir)):
        print("Datele de intrare nu corespund restrictiilor impuse\n")
        return

    print("Datele de intrare corespund restrictiilor impuse\n")

    numar = numar_minim_subsecvente(n, sir)
    print(f"{numar}\n")


if __name__ == "__main__":
    main()