2019-2020 ICPC, NERC, Northern Eurasia Finals J. Just Arrange the Icons(贪心+数学)

题目链接
大意:给你一个序列,表示所有物品的种类,让你用最少的箱子装下所有物品,大小任意但需满足:
箱子中必须只能装一种数,且必须装满活着差一个装满。 物品的大小都为1。
思路:显然,我们要枚举一些大小来获得答案,那么我们用一个集合和储存合法答案,然后check所有的答案来获得一个符合所有物品的箱子大小。
初始的集合显然要从出现最少的种类获得。
主要的地方就是check是否合法了。

//p[1] 表示出现最少次数的种类数
if(p[1]%i==0)res[0][++len[0]]=i;//如果是倍数的话,显然可以
else{//否则,我们判断是否可以通过减少塞满的箱子 来 获得一个 合法的箱子
    int l=p[1]/i;
    int r=p[1]%i;
    if(l+r>=i-1)res[0][++len[0]]=i;
}

剩下就是不断更新合法集合即可。
细节见代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e6 + 10;
#define fi first
#define se second
#define pb push_back
int t,n,a[N],cnt[N],p[N],x,res[2][N],y,len[2];
int main() {
    for(scanf("%d",&t);t;t--){
        scanf("%d",&n);x=0;
        for(int i=1;i<=n;i++)scanf("%d",&a[i]),cnt[a[i]]++;
        for(int i=1;i<=n;i++){
            if(!cnt[i])continue;
            p[++x]=cnt[i];
        }
        sort(p+1,p+1+x);len[0]=0;
        for(int i=p[1]+1;i>=1;i--){
            if(p[1]%i==0)res[0][++len[0]]=i;
            else{
                int l=p[1]/i;
                int r=p[1]%i;
                if(l+r>=i-1)res[0][++len[0]]=i;
            }
        }
        int sta=0;
        for(int i=2;i<=x;i++){
            len[sta^1]=0;
            for(int j=1;j<=len[sta];j++){
                if(p[i]%res[sta][j]==0){
                    len[sta^1]++;
                    res[sta^1][len[sta^1]]=res[sta][j];
                }else{
                    int l=p[i]/res[sta][j];
                    int r=p[i]%res[sta][j];
                    if(l+r>=res[sta][j]-1){
                        len[sta^1]++;
                        res[sta^1][len[sta^1]]=res[sta][j];
                    }
                }
            }
            sta^=1;
        }
        int an=n,num;
        for(int j=1;j<=len[sta];j++){
            int re=0;num=res[sta][j];
            for(int i=1;i<=x;i++){
                re+=p[i]/num+(p[i]%num?1:0);
            }
            an=min(an,re);
        }
        printf("%d\n",an);
        for(int i=1;i<=n;i++)cnt[a[i]]--;
    }
    return 0;
}
全部评论

相关推荐

11-03 14:38
重庆大学 Java
AAA求offer教程:我手都抬起来了又揣裤兜了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务