2020牛客国庆集训派对day3(补)

2020牛客国庆集训派对day3(补)


J

  • 题意:
      一共有n种花,每种花数量为a[i],要用这些花来做成花束,每个花束必须正好有M多花,且都是不同品种,问最多能做成多少束花

  • 思路(引用了牛客大佬的题解):

  假设能做成x束花,那么就需要花的总量为xm,一共有n种花,如果a[i]>x,也就是这种花可以用在每一束,也就是第i种花最多用x个,如果a[i]<x,那第i种花就要全部用完才可以。
我们用tot来记录在x个花束的情况下,现有的能提供多少花
也就是看当前x的情况下,每一种花所能做的贡献是多少,tot为贡献和
如果tot>xm,即供给大于需求,说明情况成立,最佳答案肯定大于等于x
如果tot<xm,即供给小于需求,说明情况不成立,组价答案肯等小于等于x
这样x我们就可以用二分来确定,条件的判断即tot与xm的关系

这里我补充一下,如果我们不要求种类不同的话,是不是我们只需要把所有花的个数除以m即可,所以这个m是理论上的最大值,我们只需要二分枚举中间的值,再判断一下是不是满足条件即可

这是代码 嫖的

#include<cstdio>
#include<iostream>
#include<queue>
#include<set>
#include<algorithm>

using namespace std;

typedef long long ll;

const int maxn=4e5+8;

ll a[maxn];
int n,m;

bool check(ll x)//x束花 
{
    
    
    ll tot=0;
    for(int i=1;i<=n;i++)tot+=min(a[i],x);
    if(tot>=x*m)return 1;
    return 0;
}
int main()
{
    
    
    std::ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--)
    {
    
    

        cin>>n>>m;
        ll sum=0;
        for(int i=1;i<=n;i++)
        {
    
    
            cin>>a[i];
            sum+=a[i];
        }
        ll l=0,r=sum/m,ans;
        while(l<=r)
        {
    
    
            ll mid=(l+r)>>1;
            if(check(mid))
            {
    
    
                l=mid+1;
                ans=mid;
            }
            else r=mid-1;
        }
        cout<<ans<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/CUCUC1/article/details/108912980