题目:
N位同学站成一排,体育老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成山峰形状。
山峰形状是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK,
则他们的身高满足T1<...Ti−1<Ti>Ti+1 …>TK(1<=i<=K)。
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成山峰形状。
输入格式:
第一行是一个整数N(2<=N<=100),表示同学的总数。第一行有n个整数,用空格分隔,第i个整数Ti(130<=Ti<=230)是第i位同学的身高(厘米)。
输出格式:
一行,这一行只包含一个整数,就是最少需要几位同学出列。
输入样例:
8
186 186 150 200 160 130 197 220
输出样例:
4
点击查看代码
思路:一遍最长上升子序列的板子,一遍最长下降子序列的板子;
最长上升子序列的状态变量表示为,dp1[i]表示以i结尾的最长上升子序列
而最长下降子序列的状态变量表示为,dp2[i]表示以i开头的最长下降子序列,
答案就是 ans = max(dp1[i]+dp2[i]-1,ans);
代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<algorithm>
#include<fstream>
#include<iostream>
#include<cstdio>
#include<deque>
#include<string>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<unordered_map>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 310000
#define N 2000100
#define endl '\n'
#define exp 1e-8
#define lowbit(x) ((x)&-(x))
const double pi = acos(-1.0);
typedef long long LL;
typedef unsigned long long ULL;
inline ULL read() {
ULL x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch>'9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
void print(ULL x) {
if (x > 9)print(x / 10);
putchar(x % 10 ^ 48);
}
int arr[N],dp1[N],dp2[N];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++) { dp1[i] = 1; dp2[i] = 1; } //dp数组初始化
for (int i = 1; i <= n; i++)
cin >> arr[i]; //读入数据
int ans = -INF; //答案置为无穷小
for (int i = 1; i <= n; i++) //求得最长上升子序列
{
for (int j = 1; j < i; j++)
{
if (arr[j] < arr[i])
{
dp1[i] = max(dp1[i], dp1[j] + 1); //dp1[i]表示以arr[i]结尾的最长上升子序列
}
}
}
for (int i = n; i >= 1; i--) //求得最长下降子序列
{
for (int j = n; j > i; j--)
{
if (arr[j] < arr[i])
{
dp2[i] = max(dp2[i], dp2[j] + 1); //dp2[i]表示以arr[i]开始的最长下降子序列
}
}
ans = max(dp1[i] + dp2[i] - 1, ans); //更新答案
}
cout << n - ans;
return 0;
}