考虑这个操作的本质,就是任意选一组 ,令 。
那么一次至多消除一个重复的数字,所以最优的次数就是重复数字的个数。(例如 就认为有 次重复, 就认为有 次重复)
考虑证明这个解存在:
把原序列排序,把重复的数字标记出来,然后从后往前做一波 的操作就可以了:
例如:
我们直接对红色这些数字进行:
for (int j = len - 1; j >= 1; --j)
b[j] += b[j + 1];
的操作,即可把原序列变成:
肉眼可见这种方法一定是对的。(注意一开始的那一个还要加回来一个最大的 )
#include<cstdio>
#include<algorithm>
int init(){
char c = getchar();
int x = 0, f = 1;
for (; c < '0' || c > '9'; c = getchar())
if (c == '-') f = -1;
for (; c >= '0' && c <= '9'; c = getchar())
x = (x << 1) + (x << 3) + (c ^ 48);
return x * f;
}
void print(int x){
if (x < 0) x = -x, putchar('-');
if (x > 9) print(x / 10);
putchar(x % 10 + '0');
}
const int N = (int) 1e5 + 5;
int a[N];
int main(){
int n = init();
for (int i = 1; i <= n; ++i)
a[i] = init();
std::stable_sort(a + 1, a + 1 + n);
int tot = 0;
for (int i = 1; i <= n; ++i)
if (a[i] == a[i - 1]) ++tot;
print(tot), putchar('\n');
}