题目大意:给出n个同学的身高,然后让n-k个同学出列,剩下的k个同学满足T1<…Ti+1>…>TK(1<=i<=K)。问最少需要多少同学出列
分别从两边求最长上升子序列,然后枚举终点,求出两者相加的最大值cnt,那么答案就是:n - cnt +1。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 110;
const int INF = 2147483640;
int n, a[maxn];
int dp[2][maxn], len;//元素个数和nlogn求最长..子序列需要的结构
int f[2][maxn];//储存以第i个元素结尾的最长..子序列的个数,便于枚举
int bin_find(bool tag, int key, int l, int r)
{
int mid;
while(l <= r)
{
mid = (l + r)>>1;
if(key <= dp[tag][mid]) r = mid - 1;
else l = mid + 1;
}
return r + 1;
}
int main()
{
scanf("%d", &n);
int i;
for(i = 1; i <= n; ++i) scanf("%d", &a[i]);
len = 0;
dp[0][0] = -INF;
for(i = 1; i <= n; ++i)
{
if(a[i] > dp[0][len])
{
dp[0][++len] = a[i];
f[0][i] = len;
}
else
{
int pos = bin_find(0, a[i], 1, len);
dp[0][pos] = a[i];
f[0][i] = pos;
}
}
len = 0;//nlogn倒着求最长..子序列
dp[1][0] = -INF;
for(i = n; i >= 1; --i)
{
if(a[i] > dp[1][len])
{
dp[1][++len] = a[i];
f[1][i] = len;
}
else
{
int pos = bin_find(1, a[i], 1, len);
dp[1][pos] = a[i];
f[1][i] = pos;
}
}
int cnt = 0;
for(i = 1; i <= n; ++i)
{
cnt = max(cnt, f[0][i] + f[1][i]);
}
printf("%d\n", n-cnt+1);
return 0;
}