题目:http://poj.org/problem?id=3670
题目大意:就是给你n个数,让你删除尽量少的数,然后让它变成最长不下降或者不上升序列。
题目大意:就是给你n个数,让你删除尽量少的数,然后让它变成最长不下降或者不上升序列。
思路:就是求这个序列的最长不上升和不下降子序列,然后 ans = n-max(n1,n2)。不上升懒得写了,直接把原数组翻个向,求LIS。
注意和最长上升子序列的区别。num[ i ] 和 a[ len ] 判断这里一样要加等号,相等也应该放进去。然后后面一定要是 upper_bound()。
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 33333;
int num[MAXN];
int a[MAXN],b[MAXN];
int lis(int n)
{
a[1] = num[0];
int len = 1;
for(int i = 1;i < n;i++)
{
if(num[i] >= a[len])
{
a[len+1] = num[i];
len++;
}
else
{
int pos = upper_bound(a+1,a+len+1,num[i])-a;
a[pos] = num[i];
}
}
return len;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i = 0;i < n;i++)
scanf("%d",&num[i]);
int n1 = lis(n);
for(int i = 0;i < n/2;i++)
swap(num[i],num[n-1-i]);
int n2 = lis(n);
//printf("n1 = %d,n2 = %d\n",n1,n2);
printf("%d\n",n-max(n1,n2));
}
return 0;
}