题目:

http://acm.hdu.edu.cn/showproblem.php?pid=6197

题意:

给定一个数组,问能不能恰好删除k个数字,使得剩下的数字构成非严格上升子序列或者非严格下降子序列

思路:

对数组正向求一次非严格LIS,然后逆向再求一次非严格LIS,两者中只要有一个长度大于等于n-k,就是符合要求的

#include <bits/stdc++.h>

using namespace std;

const int N = 100000 + 10, INF = 0x3f3f3f3f;

int a[N], dp[N];

int Lis(int *a, int n)
{
    memset(dp, 0x3f, sizeof dp);
    for(int i = 1; i <= n; i++) *upper_bound(dp, dp + n, a[i]) = a[i];//这里用upper_lower()
    return lower_bound(dp, dp + n, INF) - dp;
}
int main()
{
    int t, n, k;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d%d", &n, &k);
        for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
        int len = Lis(a, n);
        if(len >= n - k)
        {
            puts("A is a magic array.");
            continue;
        }
        reverse(a + 1, a + 1 + n);
        len = Lis(a, n);
        if(len >= n - k) puts("A is a magic array.");
        else puts("A is not a magic array.");
    }
    return 0;
}