set集合的妙用

149 阅读2分钟

AcWing5270. 最长严格递增子序列

题目描述

给定一个长度为 n 的整数序列 a1,a2,…,an将 n个序列 a 连续拼接在一起,从而得到一个新序列。 请你计算,新序列的最长严格递增子序列的长度。注意,子序列不一定连续。 例如,当 a 为 [3,2,1] 时,将 3 个 a连续拼接在一起,得到 [3,2,1,3,2,1,3,2,1],其最长严格递增子序列为 [1,2,3]。

输入描述:

第一行包含整数 T,表示共有 T 组测试数据。 每组数据第一行包含一个整数 n。 第二行包含 n 个整数 a1,a2,…,an

输出描述:

每组数据输出一行结果,一个整数,表示新序列的最长严格递增子序列的长度。

数据范围

前 5 个测试点满足 1≤T≤5,1≤n≤10。
所有测试点满足 1≤T≤20000,1≤n≤1065,1≤ai≤10^9,一个测试点内所有 n 的相加之和不超过 10^5。

输入

2
3
3 2 1
6
3 1 4 1 5 9

输出

3
5

解题思路

这题看似很难,但如果我们稍微一动脑筋,就会发现,我们要求最长递增子序列,只需要看第i次串a的叠加中,哪些数可以做为递增自序列里的数,很明显,子序列所有的数不能重复,同时要递增,这不就是stl库当中的set集合的特性吗?

  • set 是一个内部自动有序且不含重复元素的容器。
  • set 最主要的作用就是自动去重并按升序排序,适用于需要去重但是又不方便直接开数组的情况。
  • set 中的元素是唯一的,其内部采用“红黑树”实现。

巧妙利用set即可将本题轻松AC。

AC代码

#include<bits/stdc++.h>
using namespace std;

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        set<int> s;
        int n;
        cin>>n;
        for(int i=0;i<n;i++)
        {
            int t;
            cin>>t;
            s.insert(t);
        }
        cout<<s.size()<<endl;
    }
    return 0;
}