[ /tv/ /rf/ /vg/ /a/ /b/ /u/ /bo/ /fur/ /to/ /dt/ /cp/ /oe/ /bg/ /ve/ /r/ /mad/ /d/ /mu/ /cr/ /di/ /sw/ /hr/ /wh/ /lor/ /s/ /hau/ /slow/ /gf/ /vn/ /w/ /ma/ /azu/ /wn/ ] [ Main | Settings | Bookmarks | Music Player ]

No.27400 Reply
File: -.jpg
Jpg, 172.83 KB, 1440×900 - Click the image to expand
edit Find source with google Find source with iqdb
-.jpg
Пришло время помогать быдлостудентам с задачами, быдлостуденты сами ничего не сделают
Привет, анон, есть две задачи, никак не могу придумать эффективный алгоритм для их решения. Собственно, задачи:
1)Имеется заданная пара длинных строк S и T (> 50000 символов). Необходимо
   составить строку T из подстрок строки S так, чтобы количество использованных
   подстрок S было минимальным. Подстроки строки S могут быть использованы несколько
   раз и могут "перекрываться".
   Пример:
   S = "abadefghijk"
   T = "jkadbaefgab"
  
   => T = "jk" + "ad" + "ba" + "efg" + "ab"
2)В заданной последовательности элементов найти подпоследовательность максимальной
   длины, обладающую следующим свойством: она должна быть разложима на две
   непересекающиеся последовательности - неубывающую и невозрастающую.

   Пример:
   S = "11231933921"
    ^^^^ ^^^^^^
   Подходящая подпоследовательность (элементы выделены символом ^):
   "1123933921" ~ "112 9 9 " - неубывающая
                "   3 33 21"  - невозрастающая
В принципе первую можно было бы решить и в лоб, последовательно деля строку T на подстроки и проверяя, являются ли они подстроками S. Но не зря же в условии задан такой большой размер строк. А вторую я вообще не представляю, как решать, даже неэффективно.
Код не нужен, мы все равно еще многое не прошли, и я могу ничего не понять (классы, например, еще даже не начали). Просто алгоритм, а я уж реализую. Заранее спасибо.
>> No.27401 Reply
File: -.png
Png, 9.89 KB, 687×156 - Click the image to expand
edit Find source with google Find source with iqdb
-.png
Вторую задачу развалило.
>> No.27448 Reply
>>27401
Вторая решается за O(n*n), не особо напрягаясь. Так что define "эффективный"
>> No.27454 Reply
>>27448
O(1)
>> No.27455 Reply
>>27454
Как-то сомнительно.
>> No.27462 Reply
>>27448
По-моему, можно и шустрее.
Первый проход по строке - выделить возрастающие, убывающие, неубывающие и невозрастающие последовательности, максимальные для элементов, с которых они начинаются.
Второй проход - смотреть суммы неубывающей и убывающей или невозрастающей и возрастающей, оканчивающейся/начинающейся на текущем/следующем символе; если получится больше максимальной суммы, найденной раньше - запоминаем. В конце выводим результат.
Алсо, второй проход, возможно, можно включить и в первый. Будет O(n).
>> No.27463 Reply
>>27462
> с которых они начинаются
И для тех, на которых оканчиваются.
sfx
>> No.27470 Reply
>>27400
Вариант решения первой (псевдокод):
Для каждого символа T находишь длину максимальной подстроки в S:
поиск_максимальных_длин_подстрок(T, S):
    // возвращает список максимальных длин подстрок
    L = новый_список()
    для i от 1 до длина(Т):
        P = список_позиций_символа_в_строке(Т[i], S)
        если P пуст:
            задача нерешаема!
        макс_длина = 0
        пока P не пуст:
            макс_длина += 1
            для каждой позиция в P:
                если S[позиция + макс_длина] не равно T[i + макс_длина]:
                    удалить_элемент_из_списка(позиция, P)   
        добавить_элемент_в_список(макс_длина, L)
    вернуть L
Для твоего примера получится
S = "abadefghijk"
T = "jkadbaefgab"
L =  21212132121
При условии, что "список позиций символа в строке" рассчитан заранее для каждого символа (сложность расчета M * K) сложность всей функции в худшем случае (две строки из одного символа):
O(0.5 * N * M^2)
Память:
Θ(N)
где N - длина T, M - длина S, K - число символов

Далее «задача о расписании»: ищешь максимальной длины подстроку, добавляешь ее в ответ:
______efg__
jk____efg__
jkad__efg__
jkadbaefg__
jkadbaefgab
>> No.27474 Reply
>>27462
Погоди, а с чего ты взял, что невозрастающая и неубывающая подпоследовательности, на которые должны делиться искомая подпоследовательность, начинаются/оканчиваются с соседних элементов? Даже в примере они на половину как бы "проникают" друг в друга. И они не могут начинаться одновременно с одного и того же элемента, так как они не должны пересекаться.
>> No.27480 Reply
>>27470
Я в принципе уже надумал, что делать с первой задачей, проглядел вкратце твой алгоритм - по эффективности вроде бы то же самое. Но все равно спасибо, вдруг мой алгоритм соснет при реализации. Теперь бы со второй разобраться.
>> No.27481 Reply
>>27470
> O(0.5 * N * M^2)
Что то не похоже. Давай ка не на глазок, а точную апроксимацию, потому что из алгоритма это не следует. НАпример при N=n, M=1 сложность алгоритма O(n^2), а не ожидаемый тобой O(n)
>> No.27482 Reply
>>27481
Вот, кстати, алгоритм который действительно выдает O(N*M^2)
Опишем структуру Node
`struct Node
{
   const List string; // иммутабельный список чтобы не засирать память
   const int len; //длина этого списка
}`
Расположим эти структуры в двух массивах MxM - текущем и предыдущем. Индексы будут означать последние элементы подпоследовательностей - достаточную инфрмацию для оапределения допустимости добавления в них нового элемента
   Операция итерации выглядит так
1) происходит свап массивов и очистка "следующего"
2) для каждого элемента предыдущего массива производится попытка создать
а) копию
б) массив, где зачитаный элемент войдет в возрастающую подпоследовательность
в) массив, где зачитаный элемент войдет в убывающую подпоследовательность.
При этом в заполняемой клетке нового массива проверяется наличие длины, и если она больше либо равна нашей расчетной попытка считается неудачной.

Сложность алгорита O(N*M^2), затраты памяти O(M^2)
>> No.27491 Reply
>>27401
Сначала находим наибольшую неубывающую подпоследовательность, затем из оставшихся элементов находим наибольшую невозрастающую.
Сложность: O(N*log(N))
>> No.27492 Reply
>>27462
Первый проход по строке - выделить возрастающие, убывающие, неубывающие и невозрастающие последовательности, максимальные для элементов, с которых они начинаются.

Поиск наибольшей неубывающей последовательности быстрее за O(N*log(N)) не сделать.

>>27491
То, что решение правильное нужно ещё доказать, но для тестовых последовательностей [0000000, 0000001 ... 4444444] работает.
>> No.27493 Reply
>>27491
блядь, это де было так очевидно
>> No.27494 Reply
>>27492
доказывается по индукции в уме
>> No.27495 Reply
>>27492
Алсо, наибольшая неубывающая делается за O(NM), что может бысть быстрее O(Nlog(N))
>> No.27497 Reply
>>27474
> Погоди, а с чего ты взял, что невозрастающая и неубывающая подпоследовательности, на которые должны делиться искомая подпоследовательность, начинаются/оканчиваются с соседних элементов?
Не невозрастающая и неубывающая, а:
> неубывающей и убывающей или невозрастающей и возрастающей
Притом порядок значения не имеет.
>>27492>>27495
Ну я говорил о наибольших, начинающихся и оканчивающихся на определённом элементе. Делается при одном проходе, с использованием счётчиков и записью результатов в соседние массивы.
>>27491
Но наибольшая неубывающая может и не являться частью наибольшей, разложимой на неубывающую и невозрастающую. Пример: 12221254321.
>> No.27498 Reply
>>27497
> Но наибольшая неубывающая может и не являться частью наибольшей, разложимой на неубывающую и невозрастающую
Алсо, если подразумевалось взятие наибольшей неубывающей или невозрастающей, то вот ещё пример: 12345123543254321
12345 и 54321 - наибольшие неубывающая и невозрастающая, но получаем из них только 123451 и 254321 (по 6), в то время как 1235432 даёт 7. Не понимат, что там по индукции в уме доказывается.
Извиняюсь, если что-то напутал и пишу глупости в тред, лол.
>> No.27504 Reply
>>27481
> сложность алгоритма O(n^2), а не ожидаемый тобой O(n)
Откуда n^2 взялось? Цикл "для" n раз выполнится, остальное все по разу, вроде все прозрачно?

Только правильно не M^2, а M * (M + 1). Фикс:
   O(0.5 * N * M * (M + 1))
N=n, M=1 будет именно O(n)
>> No.27505 Reply
>>27481
> Давай ка не на глазок, а точную апроксимацию
поиск_максимальных_длин_подстрок(T, S):
    // возвращает список максимальных длин подстрок
    L = новый_список() // C
    для i от 1 до длина(Т): // N раз
        P = список_позиций_символа_в_строке(Т[i], S) // С
        если P пуст:                                 
            задача нерешаема! // C
        макс_длина = 0        // C
        пока P не пуст: // в худшем случае M раз
            макс_длина += 1  // C            
            для каждой позиция в P: // в худшем случае M, M - 1, ..., 3, 2, 1
                если S[позиция + макс_длина] не равно T[i + макс_длина]: 
                    удалить_элемент_из_списка(позиция, P) // C
        добавить_элемент_в_список(макс_длина, L) // C
    вернуть L 
Итого
O(0.5 * N * M * (M + 1))
>> No.27506 Reply
>>27505
> пока P не пуст: // в худшем случае M раз
лол, и ведь реально не больше M :( Мой косяк
>>27497
> Но наибольшая неубывающая может и не являться частью наибольшей, разложимой на неубывающую и невозрастающую. Пример: 12221254321.
54321 ++ 2222 же ответ, наибольшая неубывающая 54321
>> No.27514 Reply
>>27506
> 54321 ++ 2222 же ответ, наибольшая неубывающая 54321
Ох щи, условие невнимательно прочёл. Подумал, что нужно выделить последовательность подряд идущих элементов, которую можно разложить на неубывающую и невозрастающую, элементы которых тоже идут подряд. Пример из задания не посмотрел даже сразу, фэйл.
>> No.27519 Reply
>>27497
Ну хорошо, а почему именно неубывающая и убывающая или невозрастающая и возрастающая? В том же примере последовательности неубывающая и невозрастающая. И, кроме того, не факт, что именно максимальные для данных элементов последовательности должны составить искомую подпоследовательность. Ведь максимальные могут пересечься во многих местах, а по условию пересекаться они не должны.
>> No.27523 Reply
>>27498
> 12345 и 54321 - наибольшие неубывающая и невозрастающая, но получаем из них только 123451 и 254321
Почему? 123454321 получаем же, если пятерку отдадим не сразу двум последовательностям, а только одной (чтобы не пересекались).
>> No.27531 Reply
>>27519
Еще раз. ВЫделяется наибольшая последовательность неубывающая для разности, а не для всей последовательности на 2-м шаге.
По индукции доказывается, что в наибольшей последовательности содержится наибольшая невозрастающая
>> No.27595 Reply
>>27531
Так, ладно, я пока все равно не понимаю алгоритма, но потом, как будет время, перечитаю внимательнее и разберусь, спасибо.
>> No.27644 Reply
>>27595
Нет, все равно ни черта не могу понять. Распиши, пожалуйста, все сначала и поподробнее.
>> No.27684 Reply
>>27644
Ищется наибольшая неубывающая последовательность. Потом среди не вошедших в нее членов ищется наибольшая невозрастающая. Сумма их членов и будет исходной подпоследовательностью
>> No.27712 Reply
Какой курс, оп? Какой предмет?
Аноны, как вы так быстро и качественно решаете такие задачи? Это дело практтки или глубокое знание теории? Имею ли я шанс в свои 20, вот так вот просто щелкать задачки, как вы?
>> No.27721 Reply
>>27712
> Это дело практтки или глубокое знание теории?
Дело практики. А хотелось бы еще глубокое знание теории, плак-плак.
>> No.27726 Reply
>>27712
> щелкать задачки
Но зачем? В реальной работе тебе даже сортировку писать не придётся.
>> No.27732 Reply
>>27726
Это смотря над чем работаешь. Если сайтомакакой или формошлёпом - да, не придётся.
>> No.27803 Reply
>>27684
Любая наибольшая неубывающая последовательность? Тогда вот тебе такой пример:
7278578
первая попавшаяся наибольшая неубывающая последовательность:
7 78 8
Из оставшихся элементов можно составить невозрастающую последовательность длиной только в 1 элемент. Получится подпоследовательность в 5 элементов. В то время как из исходной последовательности можно составить, например, такую подпоследовательность:
7278 78
   278 8
7 7
Просто проверять для каждой наибольшей неубывающей последовательности? Так еще нужно доказать, что решение составляется именно так. Я вот так и не додумался, как ты по индукции доказывал.
>>27712
1 курс, "Практикум на ЭВМ".


Password:

[ /tv/ /rf/ /vg/ /a/ /b/ /u/ /bo/ /fur/ /to/ /dt/ /cp/ /oe/ /bg/ /ve/ /r/ /mad/ /d/ /mu/ /cr/ /di/ /sw/ /hr/ /wh/ /lor/ /s/ /hau/ /slow/ /gf/ /vn/ /w/ /ma/ /azu/ /wn/ ] [ Main | Settings | Bookmarks | Music Player ]