Совсем недавно — всего лишь неделю назад — началось новое соревнование на сайте Al Zimmermann's Programming Contests Для тех кто не знает про этот сайт: - соревнования на нём проводятся в течение трёх месяцев - Задачки, как правило, "полное NP с наворотами" (кроме последнего раунда, где автор не учёл существования Wichmann rulers) - приз выигрывает участник, представивший лучшее решение — доказательств оптимальности или объяснения использованного алгоритма не требуется — можно даже без компьютера решать ;).
Новая задачка — про игру Эрудит (Scrabble): Вам даётся последовательность букв и словарь возможных слов. Пользуясь правилами оригинального Scrabble вам нужно набрать как можно больше очков с имеющимися буквами. Основная сложность задачи в том, что вы получаете буквы по семь штук — т.е. каждый раз у вас на руках семь первых неиспользованных букв из последовательности — и в отличие от настоящего Scrabble менять буквы нельзя.
Если кому-нибудь интересно — предлагаю поучаствовать. Я сам ещё не определился — может быть после того, как в эти выходые вылечу из Google Codejam — подумаю над этой задачей. Я участвовал в предыдущем раунде, но так как в тот раз нашлось конструктивное решение (хоть и с недоказанной оптимальностью), участие "не получилось".
Автор разрешает некоторую кооперацию при решении — можно сообщать друг другу количество очков набранных в каждом сете и обсуждать high-level используемые алгоритмы и приёмы. Предлагаю если будет желание общаться в этой теме.
Одна из первых идей — попробовать сначала сложить набор максимально длинных слов из положенных 100 букв в "кроссворд", а потом уже получившийся кроссворд прикладывать к игровому полю всеми возможными способами. Способов составить кроссворд будет биллиарды, а способо приложить к игровому полю — всего лишь 2*n где n — длина первого слова.
Ещё можно попытаться всё решение выстроить на основе попытки накрыть максимальное количество клеток с тройным бонусом. То есть ищем длинное слово, которое покроет три клетки с тройным бонусом за слово, а потом все остальные ходы подбираем так, чтобы в конце игры сделать возможным этот один большой ход, где все очки за слово умножаются на 27.
Там дело обстоит немного попроще, как я понял. На каждом шаге можно использовать только 7 первых неиспользованных букв из соответствующей строчки (так называемого bag).
Да, поэтому получается такая длинная цепочка очень сильно зависящих друг от друга действий — очень сильно ветвящееся дерево. То есть ситуация не подходит для применения Local Search, а значит и всякие Simulated Annealing и прочее скорее всего не подойдут (или подойдут в очень ограниченном варианте, в постобработке решения).
Во втором комментарии я имел в виду, чтобы найти слово, частично состоящее из последних в раунде букв (конец бэга), а потом все предыдущие буквы использовать для того, чтобы подготовить доску для финального размещения последнего слова на премиальные клетки. То есть искать такую комбинацию ходов, после которой можно будет это слово разместить именно там, где нужно.
Словарь кстати там нехилый — больше 100,000 слов. У кого есть опыт работы с кроссвордами и Scrabble — какая структура лучше всего подойдёт для работы со словами? Должен быть быстрый поиск слов подходящих под конкретную маску из конкретных букв. То есть либо Trie, либо суффиксный автомат? Я склоняюсь к Trie.