zoukankan      html  css  js  c++  java
  • 《浙江科技学院第17届大学生程序设计竞赛:D:合并序列》

    一开始想的是枚举k,然后用前缀和找最小的前k个。

    但是这样其实是不对的,因为后面加入的数应该和原来的数都重新排序再找最小的k个。

    那么,这里就是个小顶堆了。

    但是这时显然枚举k,然后小顶堆检查复杂度不够。

    观察可以发现,k是满足二分性质的。k越大花费就会越小。(证明略~显而易见)

    那么就可以二分,然后小顶堆检查。

    这里有个地方,就是如果我们最后一轮没取够k个数,那么我们就可以有更优的取法。

    即一开始不取满k个,然后保证最后一次取满k个,这样才是最优的选择。

    那么,我们可以去插入0来满足最后一次取满k个。

    最后一次取满k个的条件就是Q.size()-1 % (k-1) == 0

    // Author: levil
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> pii;
    const int N = 1e5+5;
    const int M = 2e4+5;
    const LL Mod = 1e9+7;
    #define rg register
    #define pi acos(-1)
    #define INF 1e9
    #define CT0 cin.tie(0),cout.tie(0)
    #define IO ios::sync_with_stdio(false)
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO{
        inline LL read(){
            LL x = 0,f = 1;char c = getchar();
            while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
            while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
            return x*f;
        }
        void print(int x){
            if(x < 0){x = -x;putchar('-');}
            if(x > 9) print(x/10);
            putchar(x%10+'0');
        }
    }
    using namespace FASTIO;
    void FRE(){/*freopen("data1.in","r",stdin);
    freopen("data1.out","w",stdout);*/}
    
    int n,a[N];
    LL T;
    priority_queue<LL,vector<LL>,greater<LL> > SS;
    bool check(int k)
    {
        priority_queue<LL,vector<LL>,greater<LL> > Q;
        Q = SS;
        while( (Q.size()-1)%(k-1) ) Q.push(0);
        LL ans = 0;
        while(Q.size() > 1)
        {
            LL ma = 0;
            for(rg int i = 1;i <= k;++i)
            {
                ma += Q.top();
                Q.pop(); 
            }
            ans += ma;
            if(ans > T) return false;
            Q.push(ma);
        }
        return true;
    }
    int main()
    {
        n = read(),T = read();
        for(int i = 1;i <= n;++i) a[i] = read(),SS.push(a[i]);
        sort(a+1,a+n+1);
        int L = 2,r = n,ans = n;
        while(L <= r)
        {
            int mid = (L+r)>>1;
            if(check(mid))
            {
                ans = mid;
                r = mid-1;
            }
            else L = mid+1;
        }
        printf("%d
    ",ans);
        system("pause");    
    }
    View Code
  • 相关阅读:
    Centos安装VMware
    centos7下javac:未找到命令的问题
    Runtime
    JVM构架、GC垃圾回收机制的理解
    onsubmit校验表单时利用ajax的return false无效解决方法
    request和response的中文乱码问题
    Ajax,Json数据格式
    Oracle数据库对象,同义词、序列、视图、索引
    动态页面技术JSP/EL/JSTL
    会话技术Cookie&Session
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/13668505.html
Copyright © 2011-2022 走看看