Codeforces Round #579 (Div. 3)--Boxers(贪心,排序)

题目链接

题意:
给定n个质量为ai的盒子,每个盒子质量都可以改变不超过1的单位质量,求能够选出的互不相同的质量的盒子的最大数目。

题目条件:
1<=n<=150000,1<=ai<=150000。

分析:
贪心策略就是:选择尽可能大的质量的盒子,(情况一)让它质量加一(如果可以),这样选择后面的物品的时候,较其他选法,后面的盒子可选区间范围变大,能够选择的盒子也就越多(根据题目要求选的每个盒子质量互不相同选择),整体上选择到的盒子数就最大。当然还要讨论其他情况,(情况二)当所选盒子与前面选的盒子质量相同(前面选的盒子按照上面的选法已是尽可能大的了),又由于不知道后面会不会有比前面选的盒子质量小的盒子,所以应尽可能选择当前所选盒子,所以这种情况就让当前所选盒子质量减一,然后cnt++(选入选择行列中),还有一种情况(情况三)就是,前面所选盒子质量小于当前所选盒子质量,此时必定无法选择当前盒子(加一依据贪心原则必会与前面所选的某一个盒子质量相同,减一必定与前面所选质量相同),但为了后面选盒子的区间范围合理,当前盒子质量应当减一,最后一种容易忽略的情况就是(情况四),当前所选盒子质量加一等于前面所选盒子质量,此时为了若加一则无法选择当前盒子(显然依据前面的原则此方法不可取),若减一则会缩小之后可选盒子质量的区间范围,不改变当前盒子质量时就可以既增加了一个选择的盒子数,也不会减小以后可选区间范围,然后这样循环遍历判断一遍,便能O(n)求得答案,当然在遍历之前需先排序。

主要代码

int n; 
void solve(){
	VI a(n);
	REP1(i,n)
	cin>>a[i];
	sort(ALL(a));
	int cnt=0;
	for(int i=a.size()-1;i>=0;i--){
		if(i==a.size()-1){
			a[i]++,cnt++;//情况一
		}else{
			if(a[i]+1<a[i+1])
			a[i]++,cnt++;//情况一
			else
			if(a[i]==a[i+1]&&a[i]!=1)//情况二
			a[i]--,cnt++;
			else
			if(a[i]>a[i+1])//情况三
			a[i]--;
			else
			if(a[i]+1==a[i+1])//情况四
			cnt++;
		}
	}
	cout<<cnt<<endl;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
//    freopen("debug\\in.text","r",stdin);
//    freopen("debug\\out1.text","w",stdout);
    while(cin>>n)
    solve();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值