zoukankan      html  css  js  c++  java
  • [CQOI2010]扑克牌(二分答案)

    传送门

    题意:你有n种牌,第i种牌的数目为ci.另外有一种特殊的牌:joker,它的数目是m个.你可以用每种牌各一张来组成一套牌,也可以用一张joker和除了某一种牌以外的其他牌各一张组成1套牌.给出n,m和ci,你的任务是组成尽量多的套牌.每张牌最多只能用在一副套牌里(可以有牌不使用).

    分析:如果这道题你不能看出可以二分答案求解,那...我们直接二分套牌数量mid,然后对于每种牌的数量ci,如果ci小于mid,那么就需要mid-ci张joker牌,如果当前mid下所需要的joker牌的数量小于等于m,说明此次mid合法.

    想到这一步,应该都没问题.但还有一个坑,就是每一套牌只能有一张joker牌,所以我们上述最后一步判断合法性应该是:如果当前mid下所需要的joker牌的数量小于等于min(m,mid),说明此次mid合法.

    int n,m,ans;
    int c[55];
    bool check(int mid){
        int cnt=0,res=min(m,mid);//坑点
        for(int i=1;i<=n;i++){
    		if(c[i]<mid){
    	    	cnt+=mid-c[i];
    	    	if(cnt>res)return 0;
    		}
    		else return 1;
    //因为我在二分之前把c数组sort排序了一遍
    //所以如果此次c[i]>mid,之后的c[i]就都大于mid了
    //所以可以直接返回,节约时间
        }
        return 1;
    }
    int main(){
        n=read();m=read();
        for(int i=1;i<=n;i++)c[i]=read();
        sort(c+1,c+n+1);
        int l=0,r=c[n]+m,mid;//注意一下二分边界.
        while(l<=r){
    		mid=(l+r)>>1;
    		if(check(mid)){
    	    	ans=mid;
    	    	l=mid+1;
    		}
    		else r=mid-1;
        }
        printf("%d
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    dubbo学习小计
    学习java虚拟机
    学习java虚拟机
    学习java虚拟机
    学习java虚拟机
    学习设计模式
    学习设计模式
    学习设计模式
    mybatis从入门到精通(五) sqlSession API的使用
    mybatis从入门到精通(四) 动态SQL
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10365258.html
Copyright © 2011-2022 走看看