Codeforces Round #793 (Div. 2) C. LIS or Reverse LIS?(思维)

https://codeforces.com/problemset/problem/1682/C

给你一个n个正整数的数组a。

设LIS(a)表示a的最长严格递增子序列的长度。例如,

LIS([2,1–1,3–4])= 2。
LIS([3 –, 5 –, 10 –––, 20 –––) = 4。
LIS([3,1-2-4-])= 3。
我们将数组a’定义为数组a反转后得到的数组,即a’=[an,an 1,…,a1]。

数组a的美定义为min(LIS(a),LIS(a′))。

你的任务是确定数组a的最大可能的美,如果你可以任意重新排列数组a的话。

投入
输入由多个测试用例组成。第一行包含一个整数t(1≤t≤104)——测试用例的数量。测试用例的描述如下。

每个测试用例的第一行包含一个整数n (1≤n≤2⋅105),即数组a的长度

每个测试用例的第二行包含n个整数a1,a2,…,an (1≤ai≤109) —数组a的元素。

保证所有测试用例的n之和不超过2⋅105.

输出
对于每个测试用例,输出一个整数——任意重新排列元素后a的最大可能的美丽。注意
在第一个测试用例中,a = [6,6,6]和a′=[6,6,6]。LIS(a)= LIS(a’)= 1。因此美是min(1,1)=1。

在第二个测试案例中,a可以重新排列为[2,5,4,5,4,2]。那么a′=[2,4,5,4,5,2]。LIS(a)= LIS(a’)= 3。因此,美是3,可以证明这是最大可能的美。

在第三个测试案例中,a可以重新排列为[1,2,3,2]。那么a′=[2,3,2,1]。LIS(a)=3,LIS(a′)= 2。因此,美是min(3,2)=2,并且可以表明2是最大可能的美。
inputCopy
3
3
6 6 6
6
2 5 4 5 2 4
4
1 3 2 2
outputCopy
1
3
2

解析看代码内具体步骤

#include<bits/stdc++.h>
using namespace std;
const int N=200200,M=2002;
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    int T=1;
    cin>>T;
    while(T--)
    {
        map<int,int> mp;
        int n;
        cin>>n;
        int sum=0;
        for(int i=1;i<=n;i++)
        {
            int x;
            cin>>x;
            mp[x]++;
            if(mp[x]>2) sum++;//为什么要记录大于等于3个的,因为前两个在正序逆序中都已经放置过了,再多也没甚么用处
        }
        //cout<<sum<<endl;
        n-=sum;//把多余的减掉之后,就可以进行排序了
        //当某个数有两个的时候,可以左右一边一个,但是如果一个数字只有一个的时候,就必须交替放置才能满足最大化,所以一个的数量+1/2
        //就比如像 1 2 3 4 5只有放成了1 3 5 4 2才能达到最大值(1 2 3 4的时候就必须1 3 4 2或者 1 4 3 2都是最小的),由此得到规律(sum1+1)/2;
        cout<<(n+1)/2<<endl;
    }
    return 0;
}
posted @ 2022-08-06 18:07  Vijurria  阅读(37)  评论(0编辑  收藏  举报