Введение
Вы одни на острове. Остальная часть человечества мертва ( вероятно, из-за ошибки в коде пользователя 12345 ). Пиратская Орда Зомби достигла вашего острова, и они бесконечны. Пришло время надрать задницу или жевать жевательную резинку, и вы все вышли из жвачки.
проблема
Наш сценарий конца света описывается двумя целыми числами в одной строке, m
и n
. На вашем острове расположены форпосты с уникальным номером от 1 до m
. Следующие n
строки содержат каждые три целых числа, x
, y
, и z
, разделенный пробел. x
и y
являются уникальными идентификаторами двух аванпостов, а z
также количеством зомби, которые встретятся на пути между ними.
Когда вы путешествуете по пути, вы теряете z
боеприпасы и убиваете z
зомби. Если вы снова пойдете тем же путем, вы, к сожалению, встретите такое же количество зомби. Все аванпосты генерируют +1 боеприпасы каждый раз, когда вы путешествуете по пути. Вы начинаете с 100 боеприпасов на форпосте 1. Все форпосты начинаются с 0 патронов. Вы немедленно умрете, если не существует пути, для которого ваши боеприпасы превышают количество зомби на этом пути, а оставшаяся часть ваших боеприпасов превращается в убийства. Такова ваша последняя позиция.
Напишите программу, которая выводит максимальное количество зомби, которых вы можете убить для данного сценария. Если вы можете убить бесконечное количество зомби, просто вывод x
.
Пример ввода
5 6
1 2 4
2 3 4
3 1 4
2 4 10
2 5 10
1 1 50
Пример вывода
x
Предположения
- Путь будет между двумя действующими аванпостами. То есть 1 <=
x
/y
<=m
- Если путь между
x
иy
не указан, его нельзя пройти - Путь двунаправленный
- 1
m
<<= 100 - 1
n
<<= 500 - Входные данные должны быть предоставлены через stdin, прочитаны из файла или приняты в качестве единственного аргумента программы, и они должны точно соответствовать формату примера
- Время выполнения вашей программы может быть сколь угодно большим, но оно должно быть определенно конечным
Код с наименьшим количеством символов выигрывает!
1
начинается с 0 патронов? Является ли график ненаправленным?1->1
стоит 49 боеприпасов, а цикл1->2->3->1
стоит 3 боеприпаса в долгосрочной перспективе.Ответы:
Ява ( менее гротескно:
841552913301)Хорошо. В основном, я смущен, никто не представил решение. Поэтому несколько дней назад я начал пытаться решить эту проблему, потому что это здорово. , Перейдите по этой ссылке, чтобы посмотреть мой прогресс в этом через GitHub.
редактировать
Новая решающая версия, гораздо более «играемая в гольф», с исправленной проверкой цикла, идентифицированной MT0. Он также поддерживает быстрые маршруты переадресации, настраиваемые путем изменения объема памяти, доступного для виртуальной машины. Последнее БОЛЬШОЕ редактирование: понял, что у меня было несколько других мелких ошибок индекса и преждевременная оптимизация, что привело к неспособности рассмотреть довольно большое количество типов побед. Так что это исправлено, осторожно. Новая версия меньше и ниже. Для нашего эталонного маршрута,
java -Xmx2GB ZombieHordeMin
довольно хорошо справляется с задачей (будьте осторожны, это займет некоторое время).Классный фактоид
В увлекательном повороте есть МНОГИЕ решения на длину 24, и мой решатель находит одно отличное от MT0, но идентичное в принципе, за исключением того, что оно начинается с посещения других аванпостов, связанных с
1
. Захватывающий! Полностью противостоит человеческой интуиции, но совершенно оправдан.Основные решения
Так вот мой. Это (частично) игра в гольф, потому что это - экспоненциальный, почти грубый решатель силы. Я использую алгоритм IDDFS (поиск по глубине итеративного углубления вначале), так что это отличный общий решатель, который не пропускает, поэтому он решает обе части вопроса ОП, а именно:
Дайте ему достаточно энергии, памяти и времени, и он сделает это, даже карты с медленной смертью. Я потратил еще немного времени на улучшение этого решателя, и, хотя можно сделать еще больше, теперь это немного лучше. Я также интегрировал совет MT0 в отношении лучшего решения для бесконечных зомби и удалил несколько преждевременных оптимизаций из моего средства проверки win, что помешало предыдущей версии найти его, и теперь я действительно нахожу решение, очень похожее на описанное MT0.
Несколько других основных моментов:
Я описал алгоритм, чтобы сделать его более интересным для просмотра «Удалено» в целях игры в гольф. Перейдите по одной из ссылок на GitHub, чтобы увидеть версию ungolfed.Также есть множество комментариев, так что не стесняйтесь повторно реализовать свое собственное решение, основываясь на моем подходе, или покажите мне, как это должно быть сделано!История решателя
(Гольф) код
Перейдем к коду (получите версию без загадки здесь или здесь ):
Получите код от github здесь, чтобы отслеживать любые изменения, которые я делаю. Вот некоторые другие карты, которые я использовал.
Пример вывода
Пример вывода для эталонного решения:
Прочитайте вывод маршрута следующим образом
step
::source
,route-to-get-here
-ammo
. Таким образом, в приведенном выше решении вы должны прочитать его как:0
, на заставе1
с боеприпасами100
.1
используйте маршрут,1
чтобы добраться до форпоста3
с боеприпасами97
2
используйте маршрут,1
чтобы добраться до форпоста1
с боеприпасами95
Закрытие заметок
Итак, я надеюсь, что мое решение было труднее победить, но ПОЖАЛУЙСТА, ПОПРОБУЙТЕ! Используйте это против меня, добавьте параллельную обработку, улучшите теорию графов и т. Д. Пара вещей, которые я считаю, может улучшить этот подход:
убирать мертвые маршруты. Мое текущее решение не «помнит», что конкретный маршрут является тупиковым, и должно каждый раз открывать его заново. Было бы лучше отследить самый ранний момент на пути, в котором смерть неизбежна, и никогда не продвигаться дальше.сделал это...Любое другое решение, которое торгует памятью на время или позволяет агрессивно избегать тупиковых маршрутов.сделал это тоже!источник
Некоторые абстрактные заметки о решении
Если у меня будет время, я преобразую это в алгоритм ...
Для данного графа
G
существует связный подграф,G'
содержащий город1
. Если существует бесконечное решение , то будет существовать подключенный подграфG''
изG'
который содержитV
города иP
путь.Пути
P
изG''
могут быть разделены таким образом, что{p}
содержит путь , который имеет то минимальную стоимость всех путей вP
иP/{p}
является всеми другими путями (образующие связующего дерева или , возможно , цикла). Если мы предположим, чтоp
это не петлевое ребро (соединяющее оба конца с одним и тем же городом), то оно соединит два города (v1
иv2
) и будет стоитьc
боеприпасов, тогда вы (выживший) сможете затем пересечьv1
тудаv2
и обратно с общей стоимостью2c
боеприпасов. и это увеличит боеприпасы во всех городах на 2 (для общего увеличения в2|V|
пределахG''
- некоторые из которых будут собраныv1
иv2
).Если вы путешествуете из
v1
кv2
и обратноv1
несколько (m
) раз , а затем отправиться в путешествие изv1
по краям ,P/{p}
чтобы посетить все , кроме городовv1
и ,v2
прежде чем вернуться ,v1
и это займетn
пути достижения (где ,|P/{p}| ≤ n ≤ 2|P/{p}|
так как вы никогда не должны пройти путь более чем в два раза) со стоимостью,k
и города получат2m|V|
боеприпасы (опять же, некоторые из которых будут собраны во время обхода).Учитывая все это, вы можете сказать, возможно ли бесконечное решение, если тогда стоимость
k + 2mc
равна или ниже, чем общее вознаграждение2(m+n)|V|
.Существует дополнительная сложность проблемы в том, что:
1
до{p}
первой итерации, и вам необходимо учитывать эту стоимость; а такжеm
иn
достаточно низки, чтобы у вас не кончились боеприпасы, прежде чем вы сможете сделать это через первую итерацию, поскольку первая итерация будет стоить дороже, чем последующие итерации).Это приводит к 24 путям нейтрального по стоимости решения для примера в вопросе (цифры - количество посещенных городов):
источник