题目传送门:codeforces luogu
这道题目看起来毫无头绪,其实水得一逼
1.思路
这题用贪心,非常明显,可关键是怎么贪心,这也是大家在做贪心题是的困惑之一。
首先,我们通过“求套娃的最小数量”可以知道:需要吧每个序列最大化,说的通俗一点就是让尽可能的把多的套娃套在一起
可是怎么实现呢,接下来请出STL的领头人:map
我们可以把每个数出现的次数存在map里面,然后从大到小遍历数组,分成一下几步:
1.如果这个数已经用完了(m[a[i]]==0) 直接跳过
2.将这个数出现的次数- -
3.将这个数和前面的数连接,从这个位置一直向后退,把沿途的数出现的次数- -,直到退不下去了(m[a[p]]==0)结束循环,答案++(这就是一个序列)
2.代码
#include<bits/stdc++.h>
using namespace std;
int k;
map<int,int>m;
int a[200010];
bool cmp(int x,int y){return x>y;}
int cont;
int main(){
scanf("%d",&k);
while(k--){
cont=0;
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
m[a[i]]++;
}
sort(a+1,a+1+n,cmp);
//初始化 第0步
for(int i=1;i<=n;i++){
if(!m[a[i]]) continue;//如果用不了了,跳过 第1步
int t=a[i];
while(m[t]) m[t--]--;//将这个数以及沿途的数出现的次数-- 第2,3步
cont++;//答案++ 第4步
}
printf("%d\n",cont);
}
return 0;
}