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;
    }
  • 相关阅读:
    Android Media Playback 中的MediaPlayer的用法及注意事项(二)
    Android Media Playback 中的MediaPlayer的用法及注意事项(一)
    34. Search for a Range
    33. Search in Rotated Sorted Array
    32. Longest Valid Parentheses
    31. Next Permutation下一个排列
    30. Substring with Concatenation of All Words找出串联所有词的子串
    29. Divide Two Integers
    28. Implement strStr()子串匹配
    27. Remove Element
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5886993.html
Copyright © 2011-2022 走看看