Эта проблема
Определения
- Определим натуральное число
Nкак записываемое число (WN) для набора чисел
в системе счисления M, если оно может быть записано в этой системе счисления из членовUиспользуя каждый член не более одного раза. Более строгое определение "записано":
- здесь CONCATозначает конкатенацию. - Определим натуральное число
Nкак непрерывное достижимое число (CAN) для набора символов
в системе счисления Mесли оно является номером WN дляUиMа такжеN-1является номером CAN дляUиM( Другим определением может бытьNявляется CAN дляUиMесли все0.. Nчисел являются WN дляUиM). Более строгий:![enter image description here]()
вопрос
Пусть у нас есть набор из S натуральных чисел:
(мы рассматриваем ноль как натуральное число) и натуральное число M, M>1. Проблема состоит в том, чтобы найти максимальное значение CAN (MCAN) для данных U и M Данный набор U может содержать дубликаты - но каждый дубликат не может использоваться более одного раза по причине (т.е. Если U содержит {x, y, y, z}), то каждый y может использоваться 0 или 1 раз, поэтому y может быть используется в 0..2 раза). Также ожидается, что U будет действительным в системе M -numeral (то есть не может содержать символы 8 или 9 ни в одном элементе, если M=8). И, конечно же, члены U являются числами, а не символами для M (так что 11 действительна для M=10) - иначе проблема будет тривиальной.
Мой подход
Сейчас я имею в виду простой алгоритм, который просто проверяет, является ли текущее число CAN через:
- Проверьте, является ли
0WN для данныхUиM? Перейти к 2: мы сделали, MCAN является нулевым - Проверьте, является ли
1WN для данныхUиM? Перейти к 3: мы сделали, MCAN0 - ...
Итак, этот алгоритм пытается построить всю эту последовательность. Я сомневаюсь, что эта часть может быть улучшена, но может быть, это может? Теперь, как проверить, является ли число WN. Это также своего рода "замена грубой силой". Я понимаю, что для M=10 (на самом деле, поскольку мы имеем дело со строками, любой другой M не проблема) с функцией PHP:
//$mNumber is our N, $rgNumbers is our U
function isWriteable($mNumber, $rgNumbers)
{
if(in_array((string)$mNumber, $rgNumbers=array_map('strval', $rgNumbers), true))
{
return true;
}
for($i=1; $i<=strlen((string)$mNumber); $i++)
{
foreach($rgKeys = array_keys(array_filter($rgNumbers, function($sX) use ($mNumber, $i)
{
return $sX==substr((string)$mNumber, 0, $i);
})) as $iKey)
{
$rgTemp = $rgNumbers;
unset($rgTemp[$iKey]);
if(isWriteable(substr((string)$mNumber, $i), $rgTemp))
{
return true;
}
}
}
return false;
}
-so мы пробуем одну часть, а затем проверяем, может ли остальная часть быть записана с помощью рекурсии. Если это не может быть написано, мы пытаемся следующий член U Я думаю, что этот момент можно улучшить.
конкретика
Как видите, алгоритм пытается построить все числа до N и проверить, являются ли они WN. Но единственный вопрос - найти MCAN, поэтому вопрос таков:
- Может быть, конструктивный алгоритм здесь чрезмерен? И, если да, какие еще варианты можно использовать?
- Есть ли более быстрый способ определить, является ли число WN для данных
UиM? (этот пункт может не иметь смысла, если предыдущий пункт имеет положительный ответ, и мы не будем строить и проверять все числа доN).
образцы
U = {4, 1, 5, 2, 0}
M = 10
тогда MCAN = 2 (3 не может быть достигнуто)
U = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11}
M = 10
тогда MCAN = 21 (все до этого могли быть достигнуты, для 22 нет двух 2 символов всего).
в системе счисления
- здесь
в системе счисления 