Разработчик: Даниил Орешников
Переформулируем задачу. Есть $$$n$$$ блоков, у каждого есть выступ $$$b_i$$$ над основанием $$$a_i$$$. Поскольку блоки можно поворачивать, а надо разместить их как можно более плотно, очевидно, что имеет смысл рассматривать минимальную величину, на которую каждый блок будет увеличивать длину выступа. Таким образом, если в ответе будут $$$k$$$ блоков, то:
Собственно, обозначим за $$$d_i$$$ величину $$$\min(b_i + c_i, a_i - c_i)$$$, а также отдельно рассмотрим возможность ответа с $$$k = 1$$$.
Теперь проверим наличие ответа с $$$k > 1$$$. Для этого отсортируем все блоки по возрастанию $$$a_i$$$, и жадно выберем $$$t$$$ первых их них так, что $$$\sum\limits_{i=1}^t a_i \leq W$$$. Ключевое утверждение следующее:
Дальше можно решать следующим образом: переберем $$$k$$$ от $$$t + 1$$$ до $$$t + 2$$$ (ответ для $$$k = t$$$ мы уже получили) и проверим, можно ли построить ответ с таким $$$k$$$. Для этого изначально расположим $$$k - 2$$$ минимальных по $$$a_i$$$ в центре, а затем переберем варианты выбора крайних блоков:
Итого мы имеем $$$\mathcal{O}(1)$$$ вариантов, которые надо перебрать, и из них выбрать оптимальный. Здесь есть тонкости с разбором случаев, и если хотелось их избежать, можно было просто написать чуть более примитивный перебор: выбрать по два минимальных по $$$d_i$$$ из первых $$$k - 2$$$ по $$$a_i$$$ и из оставшихся $$$n - k + 2$$$, и перебрать шесть вариантов их расположения с краю; для каждого выбрать оставшиеся $$$k - 2$$$ центральных как минимальные по $$$a_i$$$ из оставшихся. Этого тоже было достаточно, чтобы уложиться в лимит по времени.