hdu5532

/*此题题意为任意去掉一个序列当中的元素后看这个序列是否满足almost sort  满足 yes,不满足 no*/
/*思路是典型的dp,通过将原序列和翻转顺序后的序列进行判断,判断原理是如果满足递增或递减 那么我们控制每次加1 那么 最终的总ans >= lis -1;*/
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;

const int maxx = 1e5 + 5;
int N;//子序列的长度
int a[maxx], dp[maxx];//a为输入的序列

struct Stack {
    int n, s[maxx];
    void init() { n = 0;}
    int find(int x){ return upper_bound(s, s + n, x) - s;} //第一个大于x值的位置
    void insert(int p, int x) {
        s[p] = x;
        n = max(n, p + 1);
    }
}S;

bool judge()
{
    S.init();
    int ans = 0;
    for(int i = 1; i <= N; i++){
        dp[i] = S.find(a[i]);//找到比当前元素大的第一个‘位置’即下标
        S.insert(dp[i], a[i]);//将元素的值与当前大小顺序的下标对应,并持续更新所需目标数组的长度
        ans = max(ans, dp[i] + 1);
    }
    return ans >= N - 1;//如果满足题目要求那么任意去掉一个元素后,剩余的每次加1最终恰好>=N-1
}

int main()
{
    int cas;//多组输入
    scanf("%d", &cas);
    while(cas--){
        scanf("%d", &N);
        for(int i = 1; i <= N; i++) scanf("%d", &a[i]);
        bool flag = judge();
        reverse(a + 1, a + N + 1);//翻转函数包含a+1不包含a+n+1 这里的主要作用是将子序列反转后看是否满足任意去掉一个 是否满足从大到小或者从小到大
        flag |= judge();
        printf("%s\n", flag ? "YES" : "NO");
    }
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值