分组

P4447 [AHOI2018初中组] 分组

我们考虑二分,但是如果是二分答案,我们发现不好做,于是我们先排序,然后使用二分查找。

我们发现每组只有最后一个数有用,所以我们对于一个组,只需要维护最后一个数和集合大小即可。每次二分,我们每次找 当前数的最后一组,若满足要求,插入,更新;否则,新开一组。

为什么是最后一组?因为最后一组最新,集合大小最小,更新它更优。

{2,3,3,4,5,7,8,9},前面成立了两组,{2,3},{3},我们需要插入的位置是后者。关于如何找最后一组,用 STL upper_bound 找到大于的第一组,往前一个就是小于等于的最后一组。

#include<cstdio>
#include<algorithm>
using namespace std;
#define Ed for(int i=h[x];~i;i=ne[i])
#define Ls(i,l,r) for(int i=l;i<r;++i)
#define Rs(i,l,r) for(int i=l;i>r;--i)
#define Le(i,l,r) for(int i=l;i<=r;++i)
#define Re(i,l,r) for(int i=l;i>=r;--i)
#define L(i,l) for(int i=0;i<l;++i)
#define E(i,l) for(int i=1;i<=l;++i)
#define W(t) while(t--)
#define Wh while

const int N=100010,INF=2e9;
int n,a[N],q[N]{INF},sz[N],cnt,ans=INF;
int main(){
    #ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
    #endif
    scanf("%d",&n);
    E(i, n)scanf("%d",a+i);
    sort(a+1,a+1+n);
    E(i, n){
        int x=a[i],k=upper_bound(q+1,q+1+cnt,x-1)-q-1;
        if(q[k]==x-1)++sz[k],q[k]=x;
        else q[++cnt]=x,sz[cnt]=1;
    }
    E(i, cnt)ans=min(ans,sz[i]);
    printf("%d",ans);
    return 0;
}

本文作者:wscqwq

本文链接:https://www.cnblogs.com/wscqwq/p/17727238.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   wscqwq  阅读(19)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起