zoukankan      html  css  js  c++  java
  • HDU 5884 Sort

    二分,验证。

    二分$k$,然后进行验证。有一个地方需要注意一下:如果$n$个数,每次合并$k$个,最后一次不能合$k$个,那么一开始需要补$0$之后再合并才是最优的。合并的时候用优先队列合并时间复杂度过高,可以用两个队列模拟一下,优化掉一个$log$。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    const double pi=acos(-1.0),eps=1e-6;
    void File()
    {
        freopen("D:\in.txt","r",stdin);
        freopen("D:\out.txt","w",stdout);
    }
    template <class T>
    inline void read(T &x)
    {
        char c=getchar(); x=0;
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) {x=x*10+c-'0'; c=getchar();}
    }
    
    const int maxn=100010;
    int n,T,k,a[maxn];
    
    bool check(int x)
    {
        queue<LL>Q[2];
        for(int i=1;i<=n;i++) Q[0].push(a[i]);
    
        int sz=n; LL sum=0,m0=a[n],m1=0;
    
        if(n%(k-1)==1){}
        else
        {
            int num; if(n%(x-1)==0) num=x-1; else num=n%(x-1);
    
            LL c=0;
            for(int i=1;i<=num;i++)
            {
                c=c+Q[0].front(); Q[0].pop();
            }
    
            sum=sum+c;
            if(sum>k) return 0;
    
            Q[1].push(c); m1=c;
    
            sz=sz-num+1;
        }
    
        if(sz==1)
        {
            if(sum>k) return 0;
            return 1;
        }
    
        while(1)
        {
            LL c=0;
            for(int i=1;i<=min(sz,x);i++)
            {
                if((!Q[0].empty())&&(!Q[1].empty()))
                {
                    if(Q[0].front()<Q[1].front()) { c=c+Q[0].front(); Q[0].pop(); }
                    else { c=c+Q[1].front(); Q[1].pop(); }
                }
                else if(!Q[0].empty()) { c=c+Q[0].front(); Q[0].pop(); }
                else { c=c+Q[1].front(); Q[1].pop(); }
            }
    
            sum=sum+c;
            if(sum>k) return 0;
    
            if(Q[0].empty()) { Q[0].push(c); m0=c; }
            else if(Q[1].empty()) { Q[1].push(c); m1=c; }
            else
            {
                if(c>=m0) { Q[0].push(c); m0=c; }
                else if(c>=m1) { Q[1].push(c); m1=c; }
            }
    
            if(sz<=x) break;
    
            sz=sz-x+1;
        }
    
        if(sum>k) return 0;
        return 1;
    }
    
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&k);
            for(int i=1;i<=n;i++) scanf("%d",&a[i]);
            sort(a+1,a+1+n);
            int L=2,R=n,ans;
            while(L<=R)
            {
                int m=(L+R)/2;
                if(check(m)) ans=m,R=m-1;
                else L=m+1;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    网络七层
    微信小程序开发工具 常用快捷键
    BZOJ 1026 windy数 (数位DP)
    BZOJ 1026 windy数 (数位DP)
    CodeForces 55D Beautiful numbers (SPOJ JZPEXT 数位DP)
    CodeForces 55D Beautiful numbers (SPOJ JZPEXT 数位DP)
    HDU 3709 Balanced Number (数位DP)
    HDU 3709 Balanced Number (数位DP)
    UVA 11361 Investigating Div-Sum Property (数位DP)
    UVA 11361 Investigating Div-Sum Property (数位DP)
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5886993.html
Copyright © 2011-2022 走看看