3 3 2 1 7 3 3 2 1 5 3 1 4 1 5
YES YES NO
题意:定义Almost Sorted Array是一个[去掉序列中的一个数,剩下的数满足单调非递减或者单调非递增的]序列,给出一个序列问它是否是Almost Sorted Array。
解题思路:纯粹的模板题,只要你有O(nlogn)复杂度的LIS(最长上升子序列)模板在手,那就不用愁了,没有的还是尽早弄一个吧
至于非递增嘛,把输入的序列反过来保存不就又是求LIS了^_^,机智如我
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #include<stack> #include<math.h> #include<vector> #include<map> #include<set> #include<stdlib.h> #include<cmath> #include<string> #include<algorithm> #include<iostream> #define exp 1e-10 using namespace std; const int N = 100005; const int M = 2010; const int inf = 2147483647; const int mod = 2009; int a[N],b[N], f[N], d[N]; // f[i]用于记录 a[0...i]的最大长度 int bsearch(const int *f, int size, const int &a) { int l=0, r=size-1; while( l <= r ) { int mid = (l+r)>>1; if( a >= d[mid-1] && a < d[mid] ) return mid; // >&&<= 换为: >= && < else if( a <d[mid] ) r = mid-1; else l = mid+1; } } int LIS(const int *a, const int &n) { int i, j, size = 1; d[0] = a[0]; f[0] = 1; for( i=1; i < n; ++i ) { if( a[i] < d[0] ) // <= 换为: < j = 0; else if( a[i] >= d[size-1] ) // > 换为: >= j = size++; else j = bsearch(d, size, a[i]); d[j] = a[i]; f[i] = j+1; } return size; } int main() { int t,i, n; scanf("%d",&t); while(t--) { memset(f,0,sizeof(f)); memset(d,0,sizeof(d)); scanf("%d",&n); for( i=0; i < n; ++i ) { scanf("%d", &a[i]); b[n-i-1]=a[i]; } if(LIS(a, n)>=n-1||LIS(b,n)>=n-1) puts("YES"); else puts("NO"); //printf("%d\n",);// 求最大递增/上升子序列(如果为最大非降子序列,只需把上面的注释部分给与替换) } return 0; }菜鸟成长记