Eng uzun o‘suvchi qism ketma-ketlik
Eng uzun o‘suvchi qism-ketma-ketlik
Masala sharti
ketma-ketligi berilgan. Uning eng katta uzunlikdagi o‘suvchi ostketma-ketligini topish talab qilinadi.
Masalan, ning eng katta o‘suvchi ostketma-ketligi bo‘ladi.
Eng uzun o‘suvchi qism-ketma-ketlik
ketma-ketligi berilgan. Uning eng katta uzunlikdagi o‘suvchi ostketma-ketligini topish talab qilinadi.
Masalan, ning eng katta o‘suvchi ostketma-ketligi bo‘ladi.
ketma-ketligining nusxasini yaratamiz va o‘sish tartibida saralaymiz. Uni deb ataymiz. Unda asl masala uchun javob va ketma-ketliklarining NOPi bo‘ladi.
ni massivining uzunligi bo‘lgan prefiksi uchun yechim deb belgilaymiz, shart shuki, pozitsiyadagi element javobga kiritilgan bo‘lsin. Ya’ni ning eng katta o‘suvchi ostketma-ketligi uzunligi, bunda javobga kiritilgan.
Bazaviy holat:
Endi umumiy holat uchun o‘tishlarni topishga harakat qilamiz. Keling o‘tishlarni tahlil qilamiz. ta’rifiga ko‘ra biz javobga ni kiritishimiz kerak. Ya’ni prefiksining o‘suvchi ostketma-ketligining oxirgi elementi bu . Unda ikki holat bor:
Demak, formula:
Javob barcha lar orasidagi ning maksimal qiymati bo‘ladi.
Keling, har bir bazaviy bo‘lmagan holat uchun NOP holatidagi kabi eng yaxshi o‘tishni ham eslab qolamiz. Ya’ni massivini ham yaratamiz, unda qaysi o‘tish qilinganligi haqidagi ma’lumotni saqlaymiz. Biz bilamizki, ning ikki xil o‘tishi bor:
Shundan so‘ng endi biz javobni tiklay olamiz. maksimal qiymatga ega bo‘lgan shunday ni topamiz. Va bo‘lguncha quyidagini qilamiz.
for (int i = 1; i <= n; i++) {
dp[i] = 1;
for (int j = 1; j < i; j++) {
if (a[j] < a[i]) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
}
for (int i = 1; i <= n; i++) {
dp[i] = 1;
p[i] = 0;
for (int j = 1; j < i; j++) {
if (a[j] < a[i] && dp[j] + 1 > dp[i]) {
dp[i] = dp[j] + 1;
p[i] = j;
}
}
}
int x = 1;
for (int i = 1; i <= n; i++) {
if (dp[i] > dp[x]) {
x = i;
}
}
vector<int> res;
while (x > 0) {
res.push_back(a[x]);
x = p[x];
}
reverse(res.begin(), res.end());