2683 - Easy ssc

De la Universitas MediaWiki

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 ⩽ 1000
  • cele n numere citite vor fi mai mici decât 50.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
10001
4 6 2 5 8 1 3 7
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 <= 1000 and all(0 <= x < 50000 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()