Ну, это классическая проблема с дп, довольно просто сделать с нисходящим подходом.
давайте определим наше состояние dp [c] [dec] [inc] - теперь мы смотрим на элемент в позиции c, элемент в конце построенной нами последовательности находится в позиции dec, а элемент в начале последовательность в положении вкл.
Итак, теперь мы можем перейти к:
- dp [c + 1] [dec] [inc] путем пропуска текущего элемента
- dp [c + 1] [c] [inc], поместив текущий элемент на оборотную сторону (действует только если a [c] <= a [dec]) </li>
- dp [c + 1] [dec] [c], поместив текущий лемент спереди (действует только если a [c]> = a [inc])
пример кода (C ++):
const int n = 7;
int a[] = {0, 0, 3, 10, 7, 6, 5, 14};
int dp[n+1][n+1][n+1];
int solve(int c, int dec, int inc)
{
if(c > n)return 0;
if(dp[c][dec][inc] != -1)return dp[c][dec][inc];
dp[c][dec][inc] = solve(c+1,dec,inc); //skip element
if(inc==0 && dec==0) //if our sequence is empty, try appending element to sequence
dp[c][dec][inc] = max(dp[c][dec][inc], 1 + solve(c+1,c,c));
else if(a[c] >= a[inc])//we can extend our array [dec, ..., inc] because current element can be put to front
dp[c][dec][inc] = max(dp[c][dec][inc], 1 + solve(c+1,dec,c));
else if(a[c] <= a[dec])//we can extend our array [dec, ..., inc] because current element can be put to back
dp[c][dec][inc] = max(dp[c][dec][inc], 1 + solve(c+1,c,inc));
return dp[c][dec][inc];
}
int main()
{
memset(dp, -1, sizeof dp);
cout<<solve(1,0,0);
}
Сложность O (n ^ 3)