题目来源:http://acm.hdu.edu.cn/php?pid=5532
题意
定义一个序列若是最多删去一个数字,能够使得这个序列成为有序序列,那么原序列被叫做almost sorted。
思路
额,这道题,眼看着大牛分分钟A了,可我依旧是迷茫,拿着草稿纸急急忙忙的画着序列,左推右推,终于发现了一丝端倪,发现这道题就是一个裸的LIS,但是又由于手残,忙着上课。。。
使用nlogn的时间复杂度,用二分写单调非递减子序列,最后把原序列反过来在来一次。
代码
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[100000+10];
int dp1[100000+10];
int dp2[100000+10];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,len=1;
scanf("%d",&n);
for(int i=0; i<n; i++)
scanf("%d",&a[i]);
dp1[1]=a[0];
for(int i=1; i<n; i++)
{
if(a[i]>=dp1[len])
dp1[++len]=a[i];
else
{
int pos=upper_bound(dp1+1,dp1+len+1,a[i])-dp1;
dp1[pos] = a[i];
}
}
int maxx=len;
for(int i=0;i<n/2;i++)
{
swap(a[i],a[n-i-1]);
}
dp2[1]=a[0];
len=1;
for(int i=1; i<n; i++)
{
if(a[i]>=dp2[len])
dp2[++len]=a[i];
else
{
int pos=upper_bound(dp2+1,dp2+len+1,a[i])-dp2;
dp2[pos]=a[i];
}
}
if(len>maxx)
maxx=len;
if(n-maxx<=1)
printf("YES\n");
else
printf("NO\n");
}
}