Codeforces Round 847 (Div. 3) D题-题解&贪心&STL-map

题目传送门: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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值