Василько і комп'ютер#502

Василько і комп'ютер (Editorial)

Автор: Костянтин Денисов

Роздробник: Павло Цікалишин

Розбір підготовано: Костянтин Денисов

Можна розв'язувати жадібно: робити перший підмасив якомога довшим, потім другий якомога довшим, і т.д.

Чому так можна: припустимо, існує оптимальне розбиття, де перший підмасив закінчується раніше, ніж це можливо. Нехай другий підмасив починається з елемента . Якщо додавання в кінець першого підмасиву не ламає можливість відсортувати його стеком, то ми можемо просто "перекласти" з початку другого підмасиву в кінець першого. Другий підмасив при цьому стає коротшим, але він все одно відсортовуваний (бо ми лише забрали з нього перший елемент). Отже завжди існує оптимальне розбиття, в якому перший підмасив максимально довгий. Те саме міркування працює для кожного наступного підмасиву.

Тому достатньо йти зліва направо і додавати елементи в поточний підмасив, доки це можливо; коли стає неможливо — робимо розріз і починаємо новий.

Ми будуємо один підмасив зліва направо і симулюємо, як би працювало сортування стеком. Коли ми кладемо елементи в стек, іноді ми змушені викидати деякі зі стеку у вихідну послідовність: якщо прийшов новий елемент , який більший за верхівку стека, то цю верхівку вже не можна тримати далі, бо інакше опиниться над меншим елементом і ми ніколи не зможемо отримати відсортований вихід.

Тому правило таке: поки top < x, ми викидаємо зі стека. Серед усіх викинутих значень запам'ятовуємо найбільше . Коли прийдемо до випадку top > x, то в цьому випадку вже не можна класти верхівку стеку до масиву, бо тоді новий елемент точно не буде стояти на своїй позиції.

— це фактично найбільше число, яке ми вже викинули зі стека у цьому підмасиві. Тобто у фінальній відсортованій послідовності воно вже стоїть десь зліва, і ми вже не можемо поставити перед ним щось менше.

Якщо в якийсь момент приходить елемент та виконується x<m, то все: поточний підмасив вже неможливо відсортувати стеком. Чому: число уже "пішло" у вихід і мусить стояти до у фінальній послідовності, але x<m, отже порядок буде неправильний і це вже не виправити ніякими майбутніми діями зі стеком.

У такому випадку ми зобов'язані розрізати масив перед і почати новий підмасив: очищаємо стек, скидаємо і збільшуємо лічильник частин.

В інших випадках (top >= m) нескладно збагнути, що можна просто перекинути весь стек у кінцевий масив, щоб він був відсортованим.

Складність. Кожен елемент один раз заходить у стек і не більше одного разу виходить зі стека, тому час , пам'ять .