**题目描述 **
小红拿到了一个数组,她准备用尽可能少的代价将该数组全部清空。
小红有两种操作:
1.直接删除一个元素
x
x
x,花费代价为 1。
2.若上一个删除的元素为
x
x
x,那么直接删除一个元素
x
+
1
x+1
x+1,花费代价为0。该操作仅当
x
+
1
x+1
x+1在数组中存在时才可
进行。
请你求出小红清空整个数组的最小代价。
输入描述:
第一行输入一个正整数
n
n
n,代表数组的大小。
第二行输入
n
n
n个正整数
a
i
a_i
ai, 用空格隔开。代表数组的元素。
1
≤
n
≤
1
0
5
1\leq n\leq10^5
1≤n≤105
1
≤
a
i
≤
1
0
9
1\leq a_i\leq10^9
1≤ai≤109
输出描述:
输出一个正整数,代表小红清空整个数组的最小代价。
示例1:
输入:
3
1 2 3
输出:
1
示例2:
输入:
5
2 1 6 5 7
输出:
2
分析:
首先对于不要求次序的数组,可以先排序,用map记录下每一个数的数量,对于连续的数就可以选择其中最小的次数来为节约次数。考虑每一个点贡献的减少次数,最终得到最优结果。
下面是完整代码:
// Problem: 小红的数组清空
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/75630/D
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
//
#include<iostream>
#include<queue>
#include<cstring>
#include<map>
#include<algorithm>
#include<vector>
#include<set>
#include<cmath>
#include<stack>
#include<random>
#include<ctime>
#define ll long long
#define ull unsigned long long
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define __int128_t int128
using namespace std;
typedef pair<int, int >PII;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e5 + 10;
int main(){
int n,a[N];
cin >> n;
map<int,int> m;
for(int i = 1; i<= n;i++){
cin >> a[i];
m[a[i]]++;
}
sort(a+1,a+n+1);
int now = 0;//能多节省的次数
for(int i = 1; i<= n;i++){
if(a[i+1] == a[i]+1 && i+1 <= n){
now += min(m[a[i+1]],m[a[i]]);//算出每一个连续的点能贡献出来的减少次数
}
}
cout << n - now << endl;
return 0;
}