С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
0 / 0 / 0
Регистрация: 01.10.2023
Сообщений: 4

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

29.10.2023, 11:47. Показов 2139. Ответов 2

Студворк — интернет-сервис помощи студентам
Добрый день! Я изучаю динамическое программирование на c++. Попалась такая задача, как Наибольшая возрастающая подпоследовательность с восстановлением. Написал я такой код, но работает только на 1 тесте. Сам алгоритм нахождения максимальной длины НВП у меня правильный, не могу разобраться в восстановлении. Делаю алгоритм со сложностью O(n^2), т. к. преподаватель сказал алгоритм побыстрее буду писать позже.
Вот код, который я написал:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <vector>
 
#define ll long long
using namespace std;
 
int main()
{
    int a;
    cin >> a;
    vector<ll> data(a, 0);
    for (int i = 0; i < a; i++)
    {
        cin >> data[i];
    }
    vector<ll> dp(a, 0);
    vector<ll> prev(a, -1);
    for (int i = 0; i < a; i++)
    {
        ll mx = 0;
        for (int j = 0; j < i - 1; j++)
        {
            if (data[j] < data[i])
            {
                mx = max(mx, dp[j]);
                prev[i] = j;
            }
            dp[i] = mx + 1;
        }
    }
    ll ans = 0;
    ll index = 0;
    for (int i = 0; i < a; i++)
    {
        if (ans < dp[i])
        {
            ans = dp[i];
            index = i;
        }
    }
    vector<ll> answer;
    while (index != -1)
    {
        answer.push_back(data[index]);
        index = prev[index];
    }
    for (int i = answer.size() - 1; i > -1; i--)
    {
        cout << answer[i] << " ";
    }
}
Я же правильно понял, что восстановление идёт через создание массива предков?
P. S. Я понял где все пошло не так, буду испралять

Добавлено через 19 минут
Цитата Сообщение от GerryKHT Посмотреть сообщение
P. S. Я понял где все пошло не так, буду испралять
Нет, я не понял. Исправил 35 строку, когда заполнял массив предков, помогло, но незначительно - проходит 2 теста.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
29.10.2023, 11:47
Ответы с готовыми решениями:

Наибольшая возрастающая подпоследовательность
Дана последовательность, требуется найти её наибольшую возрастающую подпоследовательность. ================================= Входные...

Наибольшая возрастающая подпоследовательность за O(NlogN)
Здравствуйте! Вот тут написал код НВП за О(NlogN).Но на тестирующей системе он выдает на тесты некоторые неправильные ответы.Тестов я...

наибольшая общая подпоследовательность с восстановлением ответа
#include &lt;bits/stdc++.h&gt; using namespace std; int main() { ios_base::sync_with_stdio(0); int n, m; cin &gt;&gt; n; ...

2
 Аватар для igorrr37
2872 / 2019 / 991
Регистрация: 21.12.2010
Сообщений: 3,744
Записей в блоге: 9
29.10.2023, 16:38
Лучший ответ Сообщение было отмечено GerryKHT как решение

Решение

Мне кажется что можно обойтись и без массива предков, при этом сложность восстановления будет линейная
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <vector>
#include <algorithm>
#include <list>
#include <random>
#include <ctime>
 
int main()
{
    // создаём исходный массив vct
    std::vector<int> vct{ 6, 2, 8, 5, 8, 4 }, dp(vct.size(), 1);
    int const n = vct.size();
    std::mt19937 eng{(unsigned)time(nullptr)};
    std::uniform_int_distribution uid{1, 10};
    std::generate(vct.begin(), vct.end(), [&]() {return uid(eng); });
    for (auto val : vct)
    {
        std::cout << val << " ";
    }
    std::cout << "\n\n";
 
    std::vector<int> vPrevI(vct.size(), -1); // массив предков
 
    // заполняем массив dp и массив vPrevI
    for (int i = 1; i < vct.size(); i++)
    {
        for (int j = 0; j < i; ++j)
        {
            if (vct[j] < vct[i])
            {
                if (dp[j] + 1 > dp[i])
                {
                    dp[i] = dp[j] + 1;
                    vPrevI[i] = j;
                }
            }
        }
    }
 
    // восстанавливаем ответ без массива предков
    auto imax = std::max_element(dp.begin(), dp.end());
    std::list<int> vAns;
    auto iprev = dp.rbegin();
    for (int i = imax - dp.begin(); i >= 0; i = iprev.base() - dp.begin() - 1)
    {
        // кидаем текущий элемент в ответ
        vAns.push_front(vct[i]);
        // ищем предыдущий элемент: это будет элемент вектора vct лежащий слева от текущего, имеющий значение меньше текущего и имеющий дп-шку на 1 меньше чем у текущего. 
        // Если таких несколько - можно брать любой
        iprev = std::find_if(dp.rbegin() + (dp.size() - (i + 1)), dp.rend(), [&dp, &vct, i](int& val) { 
            return val == dp[i] - 1 && vct[&val - dp.data()] < vct[i]; });
    }
 
    for (auto val : vAns)
    {
        std::cout << val << " ";
    }
    std::cout << "\n\n";
}
1
0 / 0 / 0
Регистрация: 01.10.2023
Сообщений: 4
29.10.2023, 20:35  [ТС]
Спасибо, буду разбираться!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.10.2023, 20:35
Помогаю со студенческими работами здесь

Наибольшая возрастающая подпоследовательность ряда с подвохом
Здравствуйте, появилась такая задача: нужно найти небольшую возрастающую подпоследовательность ряда, с тем условием, что любое из чисел...

Максимальная возрастающая подпоследовательность C++
пожалуйста, помогите мне решить эту проблему, когда вводится 10 и 1 2 3 1 2 3 3 4 5 6 в моем тесте правильный ответ должен быть 4 , но...

НВП (наибольшее возрастающая подпоследовательность)
Всем привет. Сегодня наткнулся на задачу в которой нужно найти НВП за O(n * log (n)) где n - длина массифа. Не могли бы вы объяснить мне...

Строго возрастающая макс. подпоследовательность
Долго ломал голову над задачей. Наконец-то нашел код (он правда, на паскале). Переделал, все хорошо. Но вот не задача: никак не могу...

Максимальная возрастающая подпоследовательность алгоритмами STL
Доброго времени суток, уважаемые форумчане. Есть задача, реализовать алгоритм вычисления максимальной возрастающей...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru