Нехай масив містить вхідну перестановку — поточний порядок вагонів. Потрібна мінімальна кількість перестановок дорівнює числу інверсій у цій перестановці.
Інверсією називається така пара елементів (m_i, m_j), що i < j, але при цьому m_i > m_j. Іншими словами, пара елементів утворює інверсію, якщо вони розташовані у неправильному порядку.
Наприклад, у масиві m = \{3, 1, 2\} інверсії утворюють пари та . Пара інверсії не утворює, оскільки числа і розташовані відносно одне одного у правильному порядку.
Кількість інверсій у масиві довжини можна порахувати за допомогою подвійного циклу: переберемо всі можливі пари , для яких 1 \le i < j \le n, і якщо m_i > m_j, збільшимо лічильник інверсій на одиницю.
Приклад
Розглянемо приклад підрахунку інверсій у перестановці. Під кожним числом запишемо кількість інверсій, які воно утворює з елементами, що стоять правіше нього. Нехай означає кількість таких індексів , для яких i < j і m[i] > m[j].
Загальна кількість інверсій дорівнює .
Вправа
Промоделюйте рішення для наступного прикладу.
Реалізація алгоритму
Оголосимо масив .
int m[100010];Послідовно обробляємо тестів.
scanf("%d", &tests);
while (tests--)
{Вхідний порядок вагонів читаємо у масив .
scanf("%d", &n);
for (i = 0; i < n; i++)
scanf("%d", &m[i]);Мінімальну кількість перестановок, необхідних для упорядкування поїзда, підраховуємо у змінній .
res = 0;
for (i = 0; i < n - 1; i++)
for (j = i + 1; j < n; j++)
if (m[i] > m[j]) res++;Виводимо відповідь.
printf("Optimal train swapping takes %lld swaps.\n", res);
}