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;
    }
  • 相关阅读:
    Navicat连接MySQL数据库的一些问题与解决方案
    从select机制谈到epoll机制
    关于VS2017提示I/O文件操作函数需要加上_s的解决办法
    LeetCode初级算法(树篇)
    LeetCode初级算法(动态规划+设计问题篇)
    LeetCode初级算法(其他篇)
    Leetcode初级算法(排序和搜索+数学篇)
    Leetcode初级算法(链表篇)
    Leetcode初级算法(字符串篇)
    机器学习之k-近邻算法
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5886993.html
Copyright © 2011-2022 走看看