переупорядочивание
Условие
Дана строка длины не более . Сколько различных строк можно получить в результате перестановки непустой, не обязательно непрерывной подпоследовательности .
По простому модулю .
Примеры
входные данные | выходные данные |
---|---|
Решение
Решение
Очевидно, что от строки нам нужно только количество вхождения каждого символа в строку.
- Двумерная динамика. Состояние — количество строк длины собранных из символов алфавита . Динамику считаем вперёд.
- Начальные состояния —
Объяснение пересчёта :
Мы зафиксировали строку длины из первых букв, а дальше докинем символов в эту строку на любую из позиции.
Почему ? Можно представить как будто мы держим строку длины и в пустые окошки расставляем.
- Ответ —
Сложность так как частота всех букв равна длине строки.
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;