Таким образом, типичное решение DP для этого будет производить массив, в котором вы знаете, какая самая длинная возможная подпоследовательность начинается с заданной позиции, скажем, у вас есть, и массив с длиной n, в котором dp [i] хранит длину самый длинный неубывающий подпоследовательность, начинающийся с элемента с индексом i.
Теперь распечатать все LNDSS (самые длинные неубывающие подпоследовательности) проще всего с помощью рекурсии. Сначала найдите фактическую длину LNDSS, выбрав значение смазки в dp. Затем запустите рекурсию для каждого элемента в dp, который имеет максимальное значение в dp (это может быть больше одного). Рекурсия по данному индексу должна печатать все последовательности, начиная с текущего индекса, длина которых равна значению dp [i]:
int st[1000];
int st_index
void rec(int index) {
if (dp[index] == 1) {
cout << "Another sequence:\n";
for (int i = 0; i < st_index; ++i) {
cout << st[i] << endl;
}
}
for (int j = index + 1; j < n; ++j) {
if (dp[j] == dp[index] - 1 && a[j] >= a[index]) {
st[st_index++] = a[j];
rec(j);
st_index--;
}
}
}
Это пример кода на c ++ (надеюсь, он понятен и на других языках). У меня есть глобальный стек, называемый стеком, в котором хранятся элементы, которые мы уже добавили. Его размер 1000 предполагает, что в LNDSS никогда не будет более 1000 элементов, но это можно увеличить. Решение не имеет наилучшего возможного дизайна, но я сосредоточился на том, чтобы сделать его простым, а не хорошо спроектированным.
Надеюсь, это поможет.