переупорядочивание

Условие задачи

Условие

Дана строка длины не более . Сколько различных строк можно получить в результате перестановки непустой, не обязательно непрерывной подпоследовательности .

По простому модулю .

Примеры

входные данныевыходные данные

Решение

Решение

Очевидно, что от строки нам нужно только количество вхождения каждого символа в строку.

  1. Двумерная динамика. Состояние — количество строк длины собранных из символов алфавита . Динамику считаем вперёд.
  2. Начальные состояния —

Объяснение пересчёта :

Мы зафиксировали строку длины из первых букв, а дальше докинем символов в эту строку на любую из позиции.

Почему ? Можно представить как будто мы держим строку длины и в пустые окошки расставляем.

  1. Ответ —

Сложность так как частота всех букв равна длине строки.

vector<vector<int>> dp(26 + 1, vector<int>(n + 1));
dp[0][0] = 1;
for (int sym = 0; sym < 26; sym++) {
  for (int sz = 0; sz <= n; sz++) {
    for (int k = 0; k <= min(sz, cnt[sym]); k++) {
      dp[sym + 1][sz] = add(dp[sym + 1][sz], mult(dp[sym][sz - k], cnk(sz, k)));
    }
  }
}

int ans = 0;
for (int i = 1; i <= n; i++) {
  ans = add(ans, dp[26][i]);
}
cout << ans;