#include<iostream>#include<vector>usingnamespace std;intmain(){int n;while(cin >> n){
vector<int>heights(n);for(int i =0; i < n; i++){
cin >> heights[i];}// 计算每个位置左边的最长上升子序列长度
vector<int>left(n,1);for(int i =0; i < n; i++){for(int j =0; j < i; j++){if(heights[i]> heights[j]){
left[i]=max(left[i], left[j]+1);}}}// 计算每个位置右边的最长下降子序列长度
vector<int>right(n,1);for(int i = n-1; i >=0; i--){for(int j = n-1; j > i; j--){if(heights[i]> heights[j]){
right[i]=max(right[i], right[j]+1);}}}// 找出最大的合唱队形长度int maxLen =0;for(int i =0; i < n; i++){
maxLen =max(maxLen, left[i]+ right[i]-1);}// 需要出列的最少人数
cout << n - maxLen << endl;}return0;}
importjava.util.*;publicclassMain{publicstaticvoidmain(String[] args){Scanner sc =newScanner(System.in);while(sc.hasNext()){int n = sc.nextInt();int[] heights =newint[n];for(int i =0; i < n; i++){
heights[i]= sc.nextInt();}// 计算每个位置左边的最长上升子序列长度int[] left =newint[n];Arrays.fill(left,1);for(int i =0; i < n; i++){for(int j =0; j < i; j++){if(heights[i]> heights[j]){
left[i]=Math.max(left[i], left[j]+1);}}}// 计算每个位置右边的最长下降子序列长度int[] right =newint[n];Arrays.fill(right,1);for(int i = n-1; i >=0; i--){for(int j = n-1; j > i; j--){if(heights[i]> heights[j]){
right[i]=Math.max(right[i], right[j]+1);}}}// 找出最大的合唱队形长度int maxLen =0;for(int i =0; i < n; i++){
maxLen =Math.max(maxLen, left[i]+ right[i]-1);}System.out.println(n - maxLen);}}}
whileTrue:try:
n =int(input())
heights =list(map(int,input().split()))# 计算每个位置左边的最长上升子序列长度
left =[1]* n
for i inrange(n):for j inrange(i):if heights[i]> heights[j]:
left[i]=max(left[i], left[j]+1)# 计算每个位置右边的最长下降子序列长度
right =[1]* n
for i inrange(n-1,-1,-1):for j inrange(n-1, i,-1):if heights[i]> heights[j]:
right[i]=max(right[i], right[j]+1)# 找出最大的合唱队形长度
max_len =max(left[i]+ right[i]-1for i inrange(n))print(n - max_len)except:break
算法及复杂度
算法:动态规划(最长上升/下降子序列)
时间复杂度:
O
(
n
2
)
\mathcal{O}(n^2)
O(n2),其中n为学生总数
空间复杂度:
O
(
n
)
\mathcal{O}(n)
O(n),需要两个长度为n的数组存储dp值