Это пахнет домашней работой. То, что вам нужно сделать, это отсортировать массив, но сделать это при минимальной стоимости свопов. Так что это скорее проблема оптимизации, чем проблема сортировки.
Жадный алгоритм, несмотря на эту работу, все, что вы делаете, это исправляете решение, сначала меняя самое дешевое (выясняя, где в списке оно принадлежит). Это, однако, не обязательно оптимально.
Пока вы никогда не меняете один и тот же элемент дважды, жадный алгоритм должен быть оптимальным.
В любом случае, вернемся к динамическому программированию, просто создайте дерево решений с помощью рекурсии, а затем обрежьте дерево, чтобы найти более оптимальные решения. Это довольно простая рекурсия.
Если вы используете более сложный алгоритм сортировки, вам будет гораздо сложнее ломать голову над этим вместе с динамическим программированием, поэтому я предлагаю вам начать с простой, медленной O(n^2)
сортировки. И надстройка над этим.
Вместо того, чтобы предоставить вам решение, я бы хотел объяснить своими словами, как работает динамическое программирование.
- Первое, что вам нужно сделать, - это найти алгоритм, который изучит все возможные решения (это может быть очень глупый алгоритм грубой силы).
- Затем вы реализуете это с помощью рекурсии, потому что динамическое программирование основано на способности быстро находить перекрывающиеся подзадачи, т.е. на рекурсии.
- При каждом рекурсивном вызове вы смотрите, где вы находитесь в своем решении, и проверяете, где вы ранее вычисляли эту часть дерева решений. Если вы сделали это, вы можете проверить, является ли текущее решение более оптимальным. , если это так, вы продолжаете, в противном случае вы закончили с этой веткой проблемы.
- Когда вы придете к окончательному решению, вы решите проблему.
Думайте о каждом рекурсивном вызове как о снимке частичного решения. Ваша задача - выяснить, как каждый рекурсивный вызов сочетается в конечном оптимальном решении.
Вот что я рекомендую вам сделать:
- Написать алгоритм рекурсивной сортировки
- Добавьте параметр в вашу рекурсивную функцию, который поддерживает стоимость этого пути выполнения, при сортировке массива добавьте к этой стоимости. Для каждого возможного свопа в любой заданной точке выполните другой рекурсивный вызов (это ответвит ваше дерево решений)
- Всякий раз, когда вы понимаете, что стоимость решения, которое вы в настоящее время изучаете, превышает ту, что у вас уже есть где-то еще, прервите (просто верните).
Чтобы иметь возможность ответить на последний вопрос, вам необходимо поддерживать разделенную область памяти, в которой вы можете индексировать в зависимости от того, где вы находитесь, ваш рекурсивный алгоритм. Если есть предварительно рассчитанная стоимость, вы просто возвращаете это значение и не продолжаете обработку (это сокращение, которое делает его быстрым).
Используя этот метод, вы даже можете основать свое решение на алгоритме перестановки перебором, он, вероятно, будет очень медленным или занимать много памяти, потому что он глуп, когда речь идет о ответвлении или обрезке но вам на самом деле не нужен специальный алгоритм сортировки, чтобы сделать эту работу, просто так будет эффективнее.
Удачи!