Блог пользователя dmkozyrev

Автор dmkozyrev, история, 6 лет назад, По-русски

Здравствуйте! Пытаюсь сдать задачу "882. Губернатор" с сайта acmp.ru. Недавно я создавал аналогичный пост для другой задачи, под которым подсказали, что в задачах такого рода должен работать жадный алгоритм и нужно лишь определить предикат для сортировки.

В этой же задаче я понял, что ответ не зависит от K и необходимо минимизировать сумму:

an·an - 1·...·a2·b1 + an·an - 1·...·a3·b2 + an·an - 1·...·a4·b3 + ... + an·bn - 1 + bn

Здесь индексами обозначена последовательность взятия.

Я генерировал маленькие случайные тесты, для которых можно перебрать все n! перестановок и пробовал подобрать предикат, но все безрезультатно. Максимально близко к случайным тестам размера 10 подошел предикат , где — произведение всех ai. На этом идеи кончились и нужна помощь. Может из-за маленького n решение предполагает динамику за O(n2) времени с памятью O(n), но с ней тоже не вяжется.

  • Проголосовать: нравится
  • -13
  • Проголосовать: не нравится

»
6 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

Сортируй типа есть пары ai,bi и aj,bj тогда первую лучше раньше брать если aibj+bi<ajbi+ai

  • »
    »
    6 лет назад, # ^ |
    Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

    К сожалению, не взлетело

    Контр-пример
    • »
      »
      »
      6 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Туплю немного , хотел написать aibj+bi<ajbi+bj

      • »
        »
        »
        »
        6 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        Да, я исправил опечатку и у Вас, и у меня. Я обновил контр-пример.

»
6 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

Там ожидается сортировка с предикатом (ai - 1) / bi > (aj - 1) / bj.

Честно говоря, я сам был бы очень признателен, если бы кто-нибудь объяснил, как и почему это работает.

»
6 лет назад, # |
  Проголосовать: нравится +10 Проголосовать: не нравится

Предположим, что ai = 1 нет, вернемся к ним позже.

Посмотрим, при каком условии будет выгодно поменять соседние элементы (a1, b1) и (a2, b2). Для этого нужно сравнить b1·a2 + b2 с b2·a1 + b1, то есть b1·(a2 - 1) с b2·(a1 - 1). Если a по разные стороны от единицы, то раньше должна идти та, что больше единицы. Другими словами, в оптимальном решении сначала идут все пары с ai больше единицы. Если a по одному сторону от единицы, то можно все разнести по разные стороны неравенства и получить валидный компаратор.

Теперь выясняется, что нам повезло, и наибольший префиксный максимум по произведению ai-х образуется всеми ai-ми большими единицы. Поэтому элементы с ai можно засунуть после них в любом порядке.

comparator
  • »
    »
    6 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Спасибо! Если рассмотреть следующий компаратор:

    const auto comp = [&](int i, int j) -> bool {
        return b[i] / (a[i] - 1) < b[j] / (a[j] - 1);
    };
    

    То он проходит. Есть ли против него контр-тест?

    • »
      »
      »
      6 лет назад, # ^ |
        Проголосовать: нравится +10 Проголосовать: не нравится

      Почти любой рандомный тест должен подойти (даже если не обращать внимание на деление на 0).

      • »
        »
        »
        »
        6 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        К сожалению, контр-тест не был обнаружен после генерации 10000 рандомных тестов на 1000 элементов. Код

        • »
          »
          »
          »
          »
          6 лет назад, # ^ |
            Проголосовать: нравится +13 Проголосовать: не нравится

          Компаратор, который вы написали в прошлом комментарии не проходит (по ссылке в коде компаратор другой). По ссылке на самом деле компаратор правильный, потому что bi положительные и можно без каких-либо дополнительных предположений поделить на них обе части (в моем описании я не учел, что bi строго положительные и слегка перемудрил).

          • »
            »
            »
            »
            »
            »
            6 лет назад, # ^ |
            Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

            Очень странный факт: результаты работы двух этих методов различны на 8-м тесте на acmp.ru. Я составил решение, в котором вызываются оба метода, а затем сравниваются по сумме с точностью до 1e-18L. Код. Срабатывает assert при сравнении по сумме. Тем не менее, проходят оба метода.