Решение задачи #28. Python Яндекс CodeRun, НВП с восстановлением ответа

Опубликовано: 13.12.2024, 17:18 | Автор: hdhAI

Вариант решения задачи на языке программирования Python с Яндекс CodeRun.
Категория: Алгоритмы.
Название задачи: НВП с восстановлением ответа.
Сложность: Средняя.
Статус решения: "Решено".

Условие задачи:
Дана последовательность, требуется найти её наибольшую возрастающую подпоследовательность.

Напомним:
Последовательность x называется подпоследовательностью последовательности y, если x получается из y удалением нескольких (возможно, нуля или всех) элементов.

Наибольшая возрастающая подпоследовательность - строго возрастающая подпоследовательность наибольшей длины.

Решение:


Python

import sys

def longest_increasing_subsequence(sequence):
    """
    Находит наибольшую возрастающую подпоследовательность.

    Args:
        sequence: Исходная последовательность.

    Returns:
        Наибольшая возрастающая подпоследовательность.
    """

    n = len(sequence)
    dp = [1] * n  # Длина наибольшей возрастающей подпоследовательности, заканчивающейся на i-м элементе
    parent = [-1] * n  # Родительский элемент для восстановления последовательности

    for i in range(1, n):
        for j in range(i):
            if sequence[j] < sequence[i] and dp[i] < dp[j] + 1:
                dp[i] = dp[j] + 1
                parent[i] = j

    # Восстановление последовательности
    max_len = max(dp)
    index = dp.index(max_len)
    result = []
    while index != -1:
        result.append(sequence[index])
        index = parent[index]
    result.reverse()

    return result

if __name__ == "__main__":
    n = int(sys.stdin.readline())
    sequence = list(map(int, sys.stdin.readline().split()))
    result = longest_increasing_subsequence(sequence)
    print(*result)
	

Объяснение кода


Инициализация:
dp: Список, где dp[i] хранит длину наибольшей возрастающей подпоследовательности, заканчивающейся на i-м элементе. Изначально все элементы равны 1, так как каждый элемент сам по себе является возрастающей подпоследовательностью длины 1.

parent: Список, где parent[i] хранит индекс элемента, предыдущего к i-му в наибольшей возрастающей подпоследовательности, заканчивающейся на i-м элементе. Это необходимо для последующего восстановления последовательности.

Основной цикл:
Внешний цикл перебирает все элементы последовательности. Внутренний цикл перебирает все предыдущие элементы.

Если текущий элемент больше предыдущего и мы можем получить более длинную возрастающую подпоследовательность, то обновляем dp[i] и parent[i].

Восстановление последовательности:
Находим индекс последнего элемента наибольшей возрастающей подпоследовательности. Используя массив parent, восстанавливаем всю последовательность, двигаясь от последнего элемента к первому.

Оптимизация:
Динамическое программирование: Позволяет эффективно решать задачу за время O(n^2).
Отсутствие лишних операций: Код оптимизирован для минимального количества операций.

Источник решения: hdhai.com

Похожие статьи
Интересное





Warning: file_put_contents(/var/www/angella1/data/www/hdhai.com/counter/count.php): Failed to open stream: Permission denied in /var/www/angella1/data/www/hdhai.com/counter.php on line 89