TGViewer
PHP | LeetCode PHP | LeetCode @easy_php_task · 1.33K subscribers
Post #797 176
Задача: 1434. Number of Ways to Wear Different Hats to Each Other
Сложность: hard

Дано n человек и 40 видов шляп, пронумерованных от 1 до 40.

Дан двумерный целочисленный массив hats, где hats[i] — список всех шляп, предпочитаемых i-м человеком.

Вернуть количество способов, которыми n человек могут носить различные шляпы друг у друга.

Поскольку ответ может быть слишком большим, вернуть его по модулю 10^9 + 7.

Пример:
Input: hats = [[3,4],[4,5],[5]]
Output: 1
Explanation: There is only one way to choose hats given the conditions.
First person choose hat 3, Second person choose hat 4 and last one hat 5.


👨‍💻 Алгоритм:

1⃣Инициализировать переменные: n - количество людей, done = 2^n - 1, MOD = 10^9 + 7, memo - двумерный массив размером 41 * done, заполненный -1, и hatsToPeople - отображение шляп на людей.

2⃣Заполнить hatsToPeople, сопоставив каждую шляпу людям, которые её предпочитают. Реализовать функцию dp(hat, mask), которая использует мемоизацию для вычисления количества способов распределения шляп.

3⃣Вернуть результат вызова dp(1, 0), который выполняет основное вычисление количества способов распределения шляп.

😎 Решение:
class Solution {
private $memo;
private $done;
private $n;
private $MOD = 1000000007;
private $hatsToPeople;

function numberWays($hats) {
$this->n = count($hats);
$this->hatsToPeople = [];

foreach ($hats as $i => $personHats) {
foreach ($personHats as $hat) {
if (!isset($this->hatsToPeople[$hat])) {
$this->hatsToPeople[$hat] = [];
}
$this->hatsToPeople[$hat][] = $i;
}
}

$this->done = pow(2, $this->n) - 1;
$this->memo = array_fill(0, 41, array_fill(0, $this->done, -1));

return $this->dp(1, 0);
}

private function dp($hat, $mask) {
if ($mask == $this->done) {
return 1;
}

if ($hat > 40) {
return 0;
}

if ($this->memo[$hat][$mask] != -1) {
return $this->memo[$hat][$mask];
}

$ans = $this->dp($hat + 1, $mask);

if (isset($this->hatsToPeople[$hat])) {
foreach ($this->hatsToPeople[$hat] as $person) {
if (($mask & (1 << $person)) == 0) {
$ans = ($ans + $this->dp($hat + 1, $mask | (1 << $person))) % $this->MOD;
}
}
}

$this->memo[$hat][$mask] = $ans;
return $ans;
}
}


Ставь 👍 и забирай 📚 Базу знаний
More from @easy_php_task
  1. Oct 17, 2026Задача: 1302. Deepest Leaves Sum Сложность: medium Дано корень бинарного дерева, вернуть с…
  2. Oct 16, 2026Задача: 760. Find Anagram Mappings Сложность: easy Вам даны два целочисленных массива nums…
  3. Oct 15, 2026Задача: 474. Ones and Zeroes Сложность: medium Дан массив двоичных строк strs и два целых…
  4. Oct 15, 2026Задача: 1273. Delete Tree Nodes Сложность: medium Дерево, укорененное в узле 0, задано сле…
  5. Oct 14, 2026Задача: 724. Find Pivot Index Сложность: easy Если задан массив целых чисел nums, вычислит…
  6. Oct 14, 2026Задача: 674. Longest Continuous Increasing Subsequence Сложность: easy Дан неотсортированн…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →