Блог пользователя e-maxx

Автор e-maxx, 14 лет назад, По-русски

Разбор задачи "D. Задача Царя?"

В этой задаче для правильного решения требуется следующая цепочка рассуждений (хотя, если некоторые шаги опустить или осуществить не полностью, всё равно получатся правильные решения :) ):

  • Заметим, что после того, как мы пришли в город n + 1, дальнейший ответ зависит только от самого левого и самого правого из непосещённых городов (и ответом на задачу будет - пойти в ближайший к n+1-ому городу из них, а потом пойти в другой город). Отсюда сразу получаем решение для случая k = n + 1, и этот случай мы дальше не рассматриваем.
  • Часть пути до города n + 1 - она покрывает какой-то отрезок городов на оси OX. Причём этот отрезок обязательно содержит точку k. Но таких отрезков может быть O(n2), поэтому пока это плохое решение.
  • Можно понять, что если человек до перехода в город n + 1 как-то походил, но не посетил самый левый на оси город или самый правый, то тогда он совершил бессмысленное и невыгодное действие. В самом деле, ведь после прихода в точку n + 1 ответ будет однозначно определяться позициям самого левого и самого правого из непосещённых городов, а таким странным действием человек не изменит ни левую, ни правую границу, т.е. только ухудшит их.
  • Остался случай, когда человек из города k пошёл в город n + 1 напрямик, и только потом спустился вниз. Во-первых, можно было просто вставить этот переход в программу, и больше не думать над ним :) Во-вторых, можно было всё же догадаться и доказать, что этот переход невыгоден. Для этого надо просто расписать два варианта пути: из k в n + 1, потом обратно в 1, потом в n (я считаю, что город 1 ближе к n + 1, чем n, и что k не совпадает ни с 1, ни с n), и второй вариант: из k в 1, потом в n + 1, потом в k + 1, потом в n. Выписыв явно эти две формулы, сократив одинаковые слагаемые, можно получить, что по неравенству треугольников второй вариант всегда лучше (не хуже).
  • Таким образом, достаточно перебирать только два вида отрезков: [1;i] для i ≥ k, и [i;n] для i ≤ k (я считаю для удобства, что города отсортированы по абсциссе).
  • Осталось аккуратно обработать каждый такой переход. Для этого перебираем все возможные i. Пусть, например, i ≤ k. Тогда надо попробовать такой переход: пойти из k в n, потом обратно в i, потом в n + 1, и потом обойти оставшуюся часть [1;i - 1]. Также обязательно надо попробовать второй переход: из k в i, потом в n, потом в n + 1, потом обойти оставшуюся часть [1;i - 1]. При i ≥ k - всё симметрично, получатся два других перехода.


Итого, не считая сортировки в начале программы (без которой, наверное, можно обойтись), получается решение за O(n).


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