版权声明:Johnson https://blog.csdn.net/m0_38055352/article/details/91356718
这段时间要沉迷刷题一段时间了,就让CSDN陪我一起吧!
一、题目大意
题目的意思是说给你一个长度为n的整数序列,要求你进行重排,重排的要求是尽可能的使每个位置上的数变大,比如原来下标1位置是1,重排后下标1位置是3,那么这就是变大了,最后要求重排后变大的下标数的最大值。
二、题目思路以及AC代码
对于这道题,还是可以很容易想到暴力的解法,那就是直接遍历所有的排列情况,然后求取每种排列情况变大的下标值,然后求取最大值,当然这显然是不可取的,复杂度太高了。
那么我们就要考虑如何给定他一个策略,按照这个策略就可以找到变大的下标数的最大值。我们可以这样,把数组中最大的数放到第二大的位置上,然后把第二大的数放到第三大的位置上,这样可以保证损失最小,也就可以保证下标变大的数尽可能的多,但需要注意的是最大的数可能有多个,第二大的数也可能有多个,需要仔细处理一下。
下面给出AC代码:
#include <iostream>
#include <algorithm>
#define MAXN 100010
using namespace std;
typedef pair<int, int> pp;
int n;
pp a[MAXN];
bool cmp(pp a, pp b) {
return a.first > b.first;
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++) {
a[i].second = i;
cin >> a[i].first;
}
sort(a, a + n, cmp);
bool* b = new bool[n];
for (int i = 0; i < n; i++) {
b[i] = false;
}
int cnt = 0;
for (int i = 0; i < n; i++) {
int j = i + 1;
while (b[j] || (j < n && a[j].first == a[i].first)) {
j++;
}
if (j >= n) break;
b[j] = true;
cnt++;
}
cout << cnt << endl;
return 0;
}
如果有问题,欢迎大家指正!!!