【16届蓝桥杯寒假刷题营】第1期DAY2
1.能选取元素的最多个数 - 蓝桥云课
问题描述
给定一个长度为 n 的数组 a,小蓝希望从数组中选择若干个元素(可以不连续),并将它们重新排列,使得这些元素
能够形成一个先严格递增然后严格递减的子序列(可以没有递增部分或递减部分)。你需要求出在满足这个条件下,
最多可以选择多少个元素。
输入格式
第一行包含一个正整数 n,表示数组的长度。(1 ≤ n ≤ 10^5)
第二行包含 n 个整数 a1, a2, ..., an-1, an。(1 ≤ ai ≤ 10^5)
输出格式
一行包含一个整数,表示最多能选多少个元素。
样例输入1
4
1 2 1 2
样例输出1
3
样例输入2
7
2 7 6 8 9 1 4
样例输出2
7
思路:
为了构成一个最多子序列,我们就要利用到所有数字。
多个相同的数字,最多只能出现两次,放在上升序列和下降序列。
最大值只能选一次,所以我们需要找出最大值,如果>=2,就-1,如果==1,那么不用减次数。
可以用min(2,ha[i]);筛选范围。1~2.
代码如下:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const ll N = 1e5+10;
ll n;
ll ha[N];
ll ans;
ll maxn = -1e9;
int main()
{
cin >> n;
for(ll i = 1 ; i <= n ; i++)
{
ll x;
cin >> x;
maxn = max(maxn,x); //找最大值
ha[x]++;
}
for(ll i = 1 ; i <= 100000 ; i++)
{
if(ha[i])
{
// cout << i << " " << ha[i] << endl;
ll cnt = min(ha[i],(ll)2);
ans += cnt;//如果是1就放入上升,如果是2就放入下降,所以+cnt即可
}
}
ll t = min(ha[maxn],(ll)2);//看看最大值有几个进入数组
if(t == 2)//删掉一个
cout << ans - 1;
else//不用删
cout << ans;
return 0;
}