Форум программистов, компьютерный форум, киберфорум
Алгоритмы
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/30: Рейтинг темы: голосов - 30, средняя оценка - 4.60
 Аватар для Krios
0 / 0 / 0
Регистрация: 12.10.2009
Сообщений: 10

Поиск самой длинной неубывающей подпоследовательности

15.10.2009, 12:57. Показов 6671. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Формулировка задачи: Реализовать на языке C или C++ алгоритм поиска для заданной числовой последовательности самой длинной неубывающей подпоследовательности. Например, для 1 0 2 1 3 2 4 3 5 это будет 1 2 3 4 5 или 0 2 3 4 5.

Хотелось бы увидеть код или хотя бы фрагменты, но если объясните алгоритм на словах, буду тоже благодарен!
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.10.2009, 12:57
Ответы с готовыми решениями:

Поиск самой длинной неубывающей подпоследовательности
Формулировка задачи: Реализовать на языке C или C++ алгоритм поиска для заданной числовой последовательности самой длинной неубывающей...

Функция нахождения самой длинной неубывающей подпоследовательности
Помогите найти ошибку //Функция находит самую длинную неубывающую подпоследовательность void Search(List *head, List*tail) { ...

Функция нахождения самой длинной неубывающей подпослед-ти
void Search(List *head, List*tail) { List *p = head->next; while (p != tail) { if (p->info < p->next->info) ...

15
 Аватар для Splitter
203 / 145 / 16
Регистрация: 13.01.2009
Сообщений: 554
15.10.2009, 13:26
внешний цикл движется по всему массиву, внутренний, начинает перебирать по тому-же массиву начиная с индекса внешнего и вглубь пока последовательность неубывающая (a[i-1]<a[i]) в отдельном массиве можно запоминать стартовый символ для последовательности, если она оказалась длинной(принцип тот-же что и для нахождения максимального элемента) и длинну этой последовательности, это понадобиться для последующего ее вывода.
0
8 / 8 / 0
Регистрация: 21.09.2009
Сообщений: 84
15.10.2009, 16:27
Цитата Сообщение от Splitter Посмотреть сообщение
внешний цикл движется по всему массиву, внутренний, начинает перебирать по тому-же массиву начиная с индекса внешнего и вглубь пока последовательность неубывающая (a[i-1]<a[i]) в отдельном массиве можно запоминать стартовый символ для последовательности, если она оказалась длинной(принцип тот-же что и для нахождения максимального элемента) и длинну этой последовательности, это понадобиться для последующего ее вывода.
Это вариант не годится. Последовательность может состоять не обязательно из рядом стоящих чисел, а, например, через один.
Другими словами задачу можно переформулировать так - какие числа нужно выбросить из списка, что бы список оказался неубывающей последовательностью причём наи-длиннейшим из всех возможных.
0
14 / 14 / 4
Регистрация: 08.10.2009
Сообщений: 114
15.10.2009, 16:45
Эта задача подробно рассматривается и приводится код на Паскале в книге Федора Меньшикова - "Решение олимпиадных задач".
1
эволюционирую потихоньку
 Аватар для TanT
468 / 466 / 91
Регистрация: 30.06.2009
Сообщений: 1,401
15.10.2009, 17:29
на скорую
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
// Реализовать на языке C или C++ алгоритм поиска для заданной числовой
// последовательности самой длинной неубывающей подпоследовательности.
// Например, для 1 0 2 1 3 2 4 3 5 это будет 1 2 3 4 5 или 0 2 3 4 5.
 
#include <iostream>
#include <vector>
 
using namespace std;
 
int main()
{ 
    int n, maxEl;
 
    vector<int> temp, nondecreasing;
    cout<<"Enter number element: "; cin>>n; 
 
    int *arr = new int[n];
    for (int i=0; i<n; i++)
    {   cout<<"enter "<<i+1<<" element "; cin>>arr[i]; }
 
    for (int i=0; i<n; i++)
    {
        temp.push_back(arr[i]);
        maxEl=arr[i];
        for (int j=i+1; j<n; j++)
        {
            if (arr[j]>=maxEl)  
            {   maxEl=arr[j]; temp.push_back(arr[j]);}
        }
        if (temp.size()>nondecreasing.size())
        { nondecreasing.clear();
            nondecreasing.insert(nondecreasing.begin(), temp.begin(), temp.end());
        }
        temp.clear();
 
        if (nondecreasing.size()>=(unsigned)(n-i))
            break;
    }
 
    cout<<"\nmax nondecreasing subsequence:";
    for (vector<int>::iterator it=nondecreasing.begin(); it<nondecreasing.end(); it++)
        cout<<" "<<*it;
    
    cout<<endl; system("pause");
    return 0;
}
1
8 / 8 / 0
Регистрация: 21.09.2009
Сообщений: 84
15.10.2009, 18:23
Я попробовал на наборе из 10 : 1 1 8 8 9 1 1 1 8 1
Предложенный вариант выдал 1 1 8 8 9 но ответ не верный - надо 1 1 1 1 1 1
Пока ошибку не нашел... ищу
0
эволюционирую потихоньку
 Аватар для TanT
468 / 466 / 91
Регистрация: 30.06.2009
Сообщений: 1,401
15.10.2009, 21:17
поправил, но требуется взгляд со стороны, на работоспосбнось, об оптимальности речи нет
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
60
61
62
63
64
65
66
// Реализовать на языке C или C++ алгоритм поиска для заданной числовой
// последовательности самой длинной неубывающей подпоследовательности.
// Например, для 1 0 2 1 3 2 4 3 5 это будет 1 2 3 4 5 или 0 2 3 4 5.
 
#include <iostream>
#include <vector>
 
using namespace std;
 
int main()
{ 
    int n, maxEl, countVal;
 
    vector<int> temp, nondecreasing, tempEqual;
    cout<<"Enter number element: "; cin>>n; 
 
    int *arr = new int[n];
    for (int i=0; i<n; i++)
    {       cout<<"enter "<<i+1<<" element "; cin>>arr[i]; }
 
    for (int i=0; i<n; i++)
    {
        temp.push_back(arr[i]);
        maxEl=arr[i];
        for (int j=i+1; j<n; j++)
        {
            if (arr[j]==maxEl)      
             temp.push_back(arr[j]);
            
            if (arr[j]>maxEl)  // если след. элемент больше     
            { countVal=0;        
                for (int k=j+1; k<n; k++)   // считаем сколько впереди текущих
                    if (arr[k]==maxEl) 
                        ++countVal;
                if ((temp.size()+countVal)>tempEqual.size())
                {    // если больше чем в буфере, переписываем буфер
                    tempEqual.clear();
                    tempEqual.insert(tempEqual.begin(), temp.begin(),temp.end());
                    for (int h=0; h<countVal; h++)
                        tempEqual.insert(tempEqual.end(), maxEl);
                }
                maxEl=arr[j]; temp.push_back(arr[j]);
            }
                
        }
        if (temp.size()>nondecreasing.size())
        { nondecreasing.clear();
            nondecreasing.insert(nondecreasing.begin(), temp.begin(), temp.end());
        }
        if (tempEqual.size()>nondecreasing.size())
        { nondecreasing.clear();
        nondecreasing.insert(nondecreasing.begin(), tempEqual.begin(), tempEqual.end());
        }
        temp.clear();
 
//      if (nondecreasing.size()>=(unsigned)(n-i))
//          break;
    }
 
    cout<<"\nmax nondecreasing subsequence:";
    for (vector<int>::iterator it=nondecreasing.begin(); it<nondecreasing.end(); it++)
        cout<<" "<<*it;
 
    cout<<endl; system("pause");
    return 0;
}
1
8 / 8 / 0
Регистрация: 21.09.2009
Сообщений: 84
15.10.2009, 21:53
Таки работает!
Осталось "причесать"
0
Эксперт С++
 Аватар для odip
7176 / 3234 / 82
Регистрация: 17.06.2009
Сообщений: 14,164
15.10.2009, 22:29
Решается методом динамического программирования.
Строим справа налево максимальную неубывающую подпосл-ть.
Используем дополнительный массив размера N.
O(N*N) действий.
0
эволюционирую потихоньку
 Аватар для TanT
468 / 466 / 91
Регистрация: 30.06.2009
Сообщений: 1,401
16.10.2009, 05:38
Цитата Сообщение от odip Посмотреть сообщение
Решается методом динамического программирования.
Строим справа налево максимальную неубывающую подпосл-ть.
Используем дополнительный массив размера N.
O(N*N) действий.
можно поподробнее, не совсем прозрачен алгоритм
0
Эксперт С++
 Аватар для odip
7176 / 3234 / 82
Регистрация: 17.06.2009
Сообщений: 14,164
16.10.2009, 11:59
Проще написать код, чем рассказывать алгоритм
Пусть оригинальный массив a[].
Строим массив b[], где b[i] будет обозначать наибольшую длину подпосл-ти в массиве a[], но начиная с позиции i.
Очевидно, что ответом на задачу будет b[0].
Массив b[] будем заполнять справа налево.
for ( i= N-1; i>=0; i-- ) { b[i]= ...; }

Как посчитать b[i], если посчитаны все b[j], где j>i.
Очевидно что с позиции i мы имеем несколько вариантов как выбрать подпосл-ть максимальной длины.
Варианты такие:
Мы не включаем a[i], а делаем сразу прыжок к j, где i<j<N.
Мы включаем a[i], а потом делаем прыжок к j, где i<j<N.
Перебираем все эти варианты и самый длинный вариант записываем в ячейку b[i].

Таким образом перебирая справа налево мы заполним весь массив b[].
Остается извлечь из b[0] максимальную длину и максимальную подпосл-ть.
1
 Аватар для Krios
0 / 0 / 0
Регистрация: 12.10.2009
Сообщений: 10
21.10.2009, 00:11  [ТС]
Цитата Сообщение от odip Посмотреть сообщение
Проще написать код, чем рассказывать алгоритм
Пусть оригинальный массив a[].
Строим массив b[], где b[i] будет обозначать наибольшую длину подпосл-ти в массиве a[], но начиная с позиции i.
Очевидно, что ответом на задачу будет b[0].
Массив b[] будем заполнять справа налево.
for ( i= N-1; i>=0; i-- ) { b[i]= ...; }

Как посчитать b[i], если посчитаны все b[j], где j>i.
Очевидно что с позиции i мы имеем несколько вариантов как выбрать подпосл-ть максимальной длины.
Варианты такие:
Мы не включаем a[i], а делаем сразу прыжок к j, где i<j<N.
Мы включаем a[i], а потом делаем прыжок к j, где i<j<N.
Перебираем все эти варианты и самый длинный вариант записываем в ячейку b[i].

Таким образом перебирая справа налево мы заполним весь массив b[].
Остается извлечь из b[0] максимальную длину и максимальную подпосл-ть.
odip, пытаюсь закодировать алгоритм, но пока не могу понять варианты как выбрать подпоследовательность. Ещё подумал о том, что если я запишу в массив b длины подпоследовательностей, то как мне потом вывести самую длинную? Запутался совсем. Напиши, пожалуйста, фрагменты кода.
0
Эксперт С++
 Аватар для odip
7176 / 3234 / 82
Регистрация: 17.06.2009
Сообщений: 14,164
21.10.2009, 18:56
А я не все написал
Массив b состоит из структуры.
В одном поле записана длина самой длинной.
А в другом поле записан номер куда переходить чтобы найти самую длинную.
Ну или использовать два массива - b_len[], b_start[].
1
 Аватар для Krios
0 / 0 / 0
Регистрация: 12.10.2009
Сообщений: 10
21.10.2009, 23:33  [ТС]
Тут теперь понятно) Когда я заполню массив b, я найду максимальный элемент и возьму соответствующий индекс, а по нему смогу вывести подп-ть.
Извини за надоедство, но можешь сам поиск подп-ти ещё подробнее объяснить?
Вот эту часть:

Цитата Сообщение от odip Посмотреть сообщение

Как посчитать b[i], если посчитаны все b[j], где j>i.
Очевидно что с позиции i мы имеем несколько вариантов как выбрать подпосл-ть максимальной длины.
Варианты такие:
Мы не включаем a[i], а делаем сразу прыжок к j, где i<j<N.
Мы включаем a[i], а потом делаем прыжок к j, где i<j<N.
Перебираем все эти варианты и самый длинный вариант записываем в ячейку b[i].
Пока что не понимаю, как посчитать длины и заполнить массив b...
0
Эксперт С++
 Аватар для odip
7176 / 3234 / 82
Регистрация: 17.06.2009
Сообщений: 14,164
21.10.2009, 23:54
я найду максимальный элемент и возьму соответствующий индекс, а по нему смогу вывести подп-ть.
Нет - ответ будет в b[0].

Еще подробнее - это написать код

посчитать длины и заполнить массив b.
Алгоритм написан.
C
1
2
3
4
for ( i= N-1; i>=0; i-- ) {
    // заполняем b[i]
    // нужно перебрать все варианты указанные выше и самый лучший из них записать в b[i]
}
1
MCSD: APP BUILDER
 Аватар для IT_Exp
8795 / 1074 / 104
Регистрация: 17.06.2006
Сообщений: 32,602
22.10.2009, 01:01
Krios,

Формулировка задачи: Реализовать на языке C или C++ алгоритм поиска для заданной числовой последовательности самой длинной неубывающей подпоследовательности.

вот программа, которая выводит все последовательности, как возрастающие, так и убывающие. тебе осталось только чуток поднатужиться, и посчитать их количество.

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
#include <algorithm>
#include <functional>
#include <iostream>
#include <locale>
#include <iterator>
 
template <typename It>
void print(It begin, It end)
{
    if (std::distance(begin, end) < 2)
        return;
    typedef typename std::iterator_traits<It>::value_type value_type;
    typedef std::ostream_iterator<value_type> O;
    std::copy(begin, end, O(std::cout, " "));
    std::cout << std::endl;
}
 
template <typename It, template <typename> class X>
static void print_all_sequences(
    It begin, It end,
    const X<typename std::iterator_traits<It>::value_type>& x)
{
    It curr = begin, next;  
    for ( ; (next = std::adjacent_find(curr, end, x)) != end; ++(curr = next))
        print(curr, curr + std::distance(curr, next) + 1);
    
    print(curr, curr + std::distance(curr, next));
}
 
int main()
{
    setlocale(LC_ALL, "");
 
    const int arr[] = {1, 0, 2, 1, 3, 2, 4, 3, 5, 3, 2, 1, 1, 2, 3};
    const size_t N = sizeof(arr) / sizeof(arr[0]);
 
    std::cout << "Исходная последовательность:" << std::endl;
    print(arr, arr+N);
 
    std::cout << std::endl << "Убывающие последовательности:" << std::endl;
    print_all_sequences(arr, arr+N, std::less_equal<int>());
 
    std::cout << std::endl << "Возрастающие последовательности:" << std::endl;
    print_all_sequences(arr, arr+N, std::greater_equal<int>());
 
    return (0);
}
Проверка: http://codepad.org/qgTUdchb
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
22.10.2009, 01:01
Помогаю со студенческими работами здесь

Найти длину самой длинной возрастающей подпоследовательности в массиве
Вводится массив. Найти в нем длину самой длинной возрастающей подпоследовательности.

В файле, состоящем из вещественных чисел, найти размер самой длинной неубывающей последовательности.
В файле, состоящем из вещественных чисел, найти размер самой длинной неубывающей последовательности. :wall: я долго думала но ни к...

Определить количество элементов в самой длинной подпоследовательности из подряд идущих нулей
Помогите, пожалуйста, решить! Очень надо, но не знаю как их решать! 1. В любой последовательности из n целых чисел, вводимых с...

Нужно найти длину самой длинной подпоследовательности, в которой равное количество 0 и 1.
Здравствуйте. Задана последовательность из 0 и 1. Нужно найти длину самой длинной подпоследовательности, в которой равное количество 0 и...

Составить программу нахождения самой длинной невозрастающей подпоследовательности данной последоват
Задана последовательность из N вещественных чисел. Составить программу нахождения самой длинной невозрастающей подпоследовательности данной...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США. Нашел на реддите интересную статью под названием «Кто-нибудь знает, где получить бесплатный компьютер или. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru