HDU 5532 Almost Sorted Array(最长非递减子序列 模板题)——2015ACM/ICPC亚洲区长春站

Almost Sorted Array

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)


Problem Description
We are all familiar with sorting algorithms: quick sort, merge sort, heap sort, insertion sort, selection sort, bubble sort, etc. But sometimes it is an overkill to use these algorithms for an almost sorted array.

We say an array is sorted if its elements are in non-decreasing order or non-increasing order. We say an array is almost sorted if we can remove exactly one element from it, and the remaining array is sorted. Now you are given an array  a1,a2,,an , is it almost sorted?
 

Input
The first line contains an integer  T  indicating the total number of test cases. Each test case starts with an integer  n  in one line, then one line with  n  integers  a1,a2,,an .

1T2000
2n105
1ai105
There are at most 20 test cases with  n>1000 .
 

Output
For each test case, please output "`YES`" if it is almost sorted. Otherwise, output "`NO`" (both without quotes).
 

Sample Input
   
   
   
   
3 3 2 1 7 3 3 2 1 5 3 1 4 1 5
 

Sample Output
   
   
   
   
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; 
}
菜鸟成长记

你可能感兴趣的:(ACM,LIS)