Dynamic Programming: Chrous

N students stand in a row, and the music teacher will invite (NK) students out of them to make the remaining K students line up in a chorus formation.     

The chorus formation refers to the formation: Suppose the K students are numbered 1, 2…, K from left to right, and their heights are respectively T1,T2, … ,TK, Then their height satisfies T1< … < Ti > Ti + 1 > … > TK( 1 ≤ i ≤ K).     

Your task is to know the heights of all N classmates, and calculate at least a few classmates to get out of the queue, so that the remaining classmates can be formed into a chorus formation.

Input format The first line of input is an integer N, which represents the total number of students.

There are n integers in the second line, separated by spaces, and the i-th integer Ti is the height (cm) of the i-th student.

Output format The output consists of one line, this line only contains an integer, that is, at least a few students are required to be listed.

data range 2 ≤ N ≤ 100, 130 ≤ Ti ≤ 230

Sample Input:

8
186 186 150 200 160 130 197 220

Sample Output:

4

Solution

Assume that the center of the optimal solution is the first ii Individual, then T1,T2, … ,Ti must be based on Ti the longest ascending subsequence at the end.

Similarly,TK, TK− 1, … ,Ti Must also be Ti the longest ascending subsequence at the end.

So you can preprocess it first O(N^2):

The length of the longest ascending subsequence from front to back ending with each point f[i]; The length of the longest ascending subsequence ending at each point from back to front g[i];

Then use a for loop O(N) to find the best Ti location.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <bits/std++.h>
using namespace std;

const int N = 110;

int n;
int h[N];
int f[N], g[N];

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i ++ )
      cin >> h[i];

    for (int i = 1; i <= n; i ++ ){
        f[i] = 1;
        for (int j = 1; j < i; j ++ )
            if (h[j] < h[i])
                f[i] = max(f[i], f[j] + 1);
    }

    for (int i = n; i; i -- ) {
        g[i] = 1;
        for (int j = n; j > i; j -- )
            if (h[j] < h[i])
                g[i] = max(g[i], g[j] + 1);
    }

    int res = 0;
    for (int i = 1; i <= n; i ++ )
       res = max(res, f[i] + g[i] - 1);

    cout << n - res;
    return 0;
}