Dynamic programming-(2 examples of the longest non-decreasing sequence)

Chorus formation

description

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.

Chorus formation refers to a formation: Suppose K students are numbered 1, 2..., K from left to right, and their heights are T1, T2,..., TK, then their height satisfies T1< …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 be out of the queue, so that the remaining classmates can be formed into a chorus formation.

format

Input format

The first line of input is an integer N (2<=N<=100), which represents the total number of students. There are n integers in the first line, separated by spaces. The i-th integer Ti (130<=Ti<=230) 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 get out of the list.

Example 1

Sample input 1

8
186 186 150 200 160 130 197 220

Sample output 1

4

limit

1s per test point

Problem solving

Obtain the longest increasing sequence (strictly increasing) and the longest decreasing sequence (strictly decreasing) respectively (that is, the longest increasing sequence for both ends respectively), and then record the point at each position as the length of the ending increase or the beginning of the decrease, min(Upper[i] + Lower[i]) is the longest choir sequence obtained by the title + 1 (the middle position is calculated twice), and the total number of people minus the length of the longest choir sequence is the solution for the title .

Code

#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
const int maxn = 102;
int T[maxn], dp[maxn];
int Upper[maxn], Lower[maxn];

int up_bound(int l, int r, int x) {
    
    
    while (l < r) {
    
    
        int mid = (l + r) >> 1;
        if (x <= dp[mid]) {
    
      //目标!!!!!!(以后记住!!!)
            r = mid;
        } else {
    
    
            l = mid + 1;
        }
    }
    return l;
}

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

    int len1 = 1;
    dp[1] = T[1];
    Upper[1] = 1;
    for (int i = 2; i <= N; i++) {
    
    
        if (T[i] > dp[len1]) {
    
    
            dp[++len1] = T[i];
            Upper[i] = len1;
        } else {
    
    
            int up = up_bound(1, len1, T[i]);
            dp[up] = T[i];
            Upper[i] = up;
        }
    }

    int len2 = 1;
    dp[1] = T[N];	//这里注意从后面开始遍历的索引的对应关系
    Lower[N] = 1;
    for (int i = N - 1; i >= 1; i--) {
    
    
        if (T[i] > dp[len2]) {
    
    
            dp[++len2] = T[i];
            Lower[i] = len2;
        } else {
    
    
            int up = up_bound(1, len2, T[i]);
            // cout << up << "," << T[i] << endl;
            dp[up] = T[i];
            Lower[i] = up;
        }
    }

    int ans = 0;
    for (int i = 1; i <= N; i++) {
    
    
        ans = max(ans, Upper[i] + Lower[i]);
    }
    cout << N - ans + 1 << endl;

    system("pause");
    return 0;
}

Guess you like

Origin blog.csdn.net/qq_45349225/article/details/109410113