Loading [MathJax]/jax/output/CommonHTML/jax.js

Розбір 4 дня літньої школи в Хусті 2024 | Articles

A. Найбільша зростаюча підпослідовність

Відеорозбір

B. Коля, Вася і двері

Завдання задачі — порахувати, скільки символів треба видалити в підрядку, аби він перетворився у паліндром.

Нехай dp[l][r] — відповідь на задачу для підвідрізка від l-го до r-го символа.

Початкові стани: для проміжка довжини 1 маємо dp[i][i]=0, а для проміжка довжини 2 dp[i][i+1] дорівнює 0 або 1.

Для підрядків з довжиною хоча б 3 можемо розглянути крайні елементи. Якщо вони рівні (sl=sr), тоді ми можемо визначити що dp[l][r]=dp[l+1][r1]. У випадку коли символи різні (slsr), то треба видалити один із цих символів тобто dp[l][r]=min(dp[l][r1],dp[l+1][r])+1.

C. Супер послідовність

Перш за все нам потрібно перевірити першу умову, що числа зростають. Якщо це не так, тоді ми знаємо що відповідь — No..

Розглянемо таку динаміку: dp[s]= true/false — чи можна отримати суму чисел s використовуючи лише розглянуті числа.

Коли ми розглядаємо нове число a тоді якщо dp[s]=true, тоді ми можемо сказати що тепер dp[s+a]= true і це треба зробити по усіх значеннях s.

Ми будемо розглядати числа в порядку зростання. Перед тим як розглянути чергове число ai, перевіримо чи ми з менших чисел могли утворити суму рівну поточному числу (перевірити значення dp[ai]). Якщо dp[ai]= true, то це означає що порушується умова на супер послідовність.

D. Збалансоване парування

Для розв’язання цієї задачі можна переформулювати задачу так: для кожного j треба порахувати мінімальну незбалансованість для j пар. Тоді щоб отримати відповідь на початкову задачу нам треба знайти найбільше j, для якого незбалансованість не перевищує k.

Посортуємо масив за зростанням. Оптимально парувати тільки ті елементи, які є сусідніми в посортованому масиві.

Нехай dp[i][j] — мінімальна незбалансованість, якщо ми розглянули перші i чисел та утворили з них j пар.

Маємо два переходи.

  • Спаруємо сусідні (у посортованому масиві) елементи ai1 та ai. Оновимо dp[i][j] значенням dp[i2][j1]+(aiai1).

  • Не паруємо ai із жодним іншим елементом. У цьому разі оновимо dp[i][j] значенням dp[i1][j].

E. Пробірки

Позначимо f(m) відповідь на задачу залежно від кількості студентів m. Ця функція є опуклою вгору, тобто виконується f(m+2)f(m+1)f(m+1)f(m). Нам потрібно знайти відповідь для k студентів f(k).

Розглянемо функцію g(m)=f(m)λm для деякого параметра λ. Функція g(m) також є опуклою вгору, як сума опуклої вгору та лінійної.

Термінами нашої задачі можна сказати, що g(m) — це максимальне задоволення студентів, щоб роздати пробірки m студентам, причому ми «платимо» (віднімаємо від задоволення) λ одиниць за кожного студента.

Тепер розглянемо дещо іншу задачу, ніж початкова. Потрібно роздати пробірки студентам, щоб максимізувати сумарне задоволення, коли за кожного студента «платимо» λ одиниць, причому дозволено роздати пробірки скільком завгодно студентам.

Цю задачу можна розв’язати таким динамічним програмуванням. Будемо підтримувати два значення в динаміці: dp[i].first — власне відповідь на задачу, коли розглянули перших i пробірок, і dp[i].second — оптимальна кількість студентів, яким потрібно роздати ці пробірки. Перехід динаміки: dp[i].first=maxjdp[j].first+c[j+1][i]λ, де c[j+1][i] — кількість різних речовин на проміжку [j+1,i]. У цій динаміці в першу чергу максимізовуємо значення first, а в другу чергу максимізовуємо second.

Тоді dp[n].first — відповідь, коли роздамо всі n пробірок. Тут не накладаються обмеження на кількість студентів, тому dp[n].first=maxmg(m) — максимальному значенню функції g для всіх можливих кількостей студентів.

Позначимо mопт оптимальну кількість студентів для деякого параметра λ. Тобто dp[n].first=maxmg(m)=g(mопт). Якщо mопт=k, тоді можна знайти значення f(k)=g(k)+λk — це й буде відповіддю на задачу.

Як підібрати таке λ, щоб для нього виконувалося mопт=k? Зауважимо, що при λ=0 (нічого не «платимо» за кількість студентів), оптимально роздати пробірки n студентам, тобто mопт=n для λ=0. А коли λ=n (дорого «платити» за студентів), то вигідно взяти лише одного студента, тобто mопт=1 для λ=n. Чим більше λ, тим дорожче «платити» за студентів, тим буде меншою оптимальна кількість студентів mопт.

Для знаходження параметра λ скористаємось двійковим пошуком. Потрібно знайти таке найбільше λ, що mоптk, тобто dp[n].secondk.

Відповіддю на задачу буде f(k)=g(mопт)+λk=dp[n].first+λk.

Складність розв’язку: O(n2logn).

F. Податки

Нехай dp[i][0] — відповідь на задачу для перших i місяців, якщо Зеник після цих місяців перебуває на загальній системі, а dp[i][1] — якщо на спрощеній.

Переходи динаміки:

  • Зеник був на загальній, залишається на загальній: dp[i][0]dp[i+1][0].

  • Зеник був на загальній, переходить на спрощену: dp[i][0]dp[i+1][1].

  • Зеник був на спрощеній, залишається на спрощеній: dp[i][1]dp[i+1][1].

  • Зеник був на спрощеній, переходить на загальну: dp[i][1]dp[k][0], де k=min(i+m,n). Тут ми повинні забезпечити, що Зеник залишатиметься на загальній системі принаймні m місяців (або до кінця).

Щоб відновити відповідь, потрібно для кожного стану dp підтримувати, яким попереднім станом ми його оновили.

Складність розв’язку: O(n).

G. Холодильники

Це задача про рюкзак.

Нехай dp[i][j] — максимальний прибуток, який ми отримаємо, якщо ми розглянули i холодильників, та купили холодильників на суму j гривень.

Переходи динаміки:

  • Не купуємо i-ий холодильник: dp[i][j]dp[i+1][j].

  • Купуємо i-ий холодильник за ai гривень: dp[i][j]dp[i+1][j+ai].

Складність розв’язку: O(nmax\_sum)=O(nnmax\_a)=O(n2max\_a).

H. Чемоданний настрій

Потрібно відсортувати чемодани за об’ємом. Після цього зробимо динаміку схожу на найдовшу зростаючу підпослідовність.

I. Послідовність

Послідовність довжини n2, яка задовольняє вимоги, має вигляд xxxxxxx=47xxxxx (якщо починається цифрою 4) або xxxxxxx=7xxxxxx (якщо починається цифрою 7).

Кількість потрібних рядків рядків довжини n порахуємо динамікою dp[n]=dp[n2]+dp[n1]. Значення динаміки — це послідовність чисел Фібоначчі, яка починається зі значень dp[0]=1,dp[1]=2.

Якщо k>dp[n], то відповіді не існує.

Щоб знайти k-у послідовність, ставимо цифри по черзі зліва направо.

Нехай n2. Тоді виконуємо такий процес.

  • Якщо kdp[n2], то послідовність xxxxxxx має вигляд 47xxxxx. Ставимо цифри 47 і зменшуємо n на 2.

  • Якщо k>dp[n2], то послідовність xxxxxxx має вигляд 7xxxxxx. Зменшуємо k на dp[n2], ставимо цифру 7 і зменшуємо n на 1.

Код розв’язку.

J. Пробний тур

Порахуємо розмір кожної з компонент зв’язності. Тепер для кожної кількості балів від 0 до n порахуємо чи можемо ми її набрати. Це можна зробити за допомогою динаміки про рюкзак. Для оптимізації використаємо бітсети.

Код розв’язку.

K. Депутатські щасливі числа

Нехай dp[i][j][0/1] — кількість щаслиих чисел довжини i, цифри змінюються j разів і визначена перша цифра (0 відповідає за 4, 1 відповідає за 7). Ми можемо легко перерахувати таку динаміку так:

  • dp[i+1][j][0] += dp[i][j][0]

  • dp[i+1][j+1][0] += dp[i][j][1]

  • dp[i+1][j+1][1] += dp[i][j][0]

  • dp[i+1][j][1] += dp[i][j][1]

Тепер переберемо довжину відповіді — len. Якщо jluckydp[len][j][0]+dp[len][j][1] < n, то ця довжина є замалою. Коли ми переходимо до len+1, потрібно від n відняти кількість депутатських щасливих чисел довжини len. Тепер коли в нас є фіксована довжина, потрібно знайти n-е депутатське щасливе число число довжини len. Для цього будемо йти від старших цифр до молодших і пробувати жадібно ставити 4 або 7. Перевіряти чи можемо поставити ми будемо за допомогою порахованої перед тим динаміки.

L. Відрізки

Впорядкуємо відрізки за правим кінцем в порядку зростання. Якщо праві кінці збігаються, то за лівим у порядку спадання. Стиснемо координати і будемо розглядати тільки цікаві (ті які є кінцем хоча б одного відрізка).

Порахуємо динаміку dp[x] — відповідь на задачу, якщо останній відрізок, який ми взяли має лівий кінець в координаті x. Коли ми розглядаємо i-тий відрізок, то ми вже розглянути всі, які закінчуються раніше. Нам підходять всі відрізки, у яких лівий кінець є лівіше ніж лівий кінець i-того відрізка. Оновимо dp[l[i]]=maxx<l[i]dp[x]+1. Щоб шукати максимум використаємо дерево Фенвіка або дерево відрізків.

Код розв’язку.

M. Байрактар

Розбір задачі доступний на сайті - Обласна iнтернет олiмпiада 2023 - Тур 2 (розбір).