【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 
#include 
#include 
#include 
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;
}

【16届蓝桥杯寒假刷题营】第1期DAY2_第1张图片

你可能感兴趣的:(算法,数据结构,蓝桥杯)