Hdu 5884

Posted repulser

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hdu 5884相关的知识,希望对你有一定的参考价值。

hdu 5884 Sort

题意:

n个有序序列的归并排序。每次可以选择不超过k个序列进行合并,合并代价为这些序列的长度和,总的合并代价不能超过T, 问k最小是多少。

解法:

1:首先想到的是二分这个答案k,然后check每个k是否可行
2:对于每个k,总共需要归并n-1个数,每次归并k-1个数
所以当(n-1)%(k-1)!=0的时候,会出现归并不能最大化个数的情况,这样会影响二分的单调性
我们先取(n-1)%(k-1)个小的数凑成一次k,接下来的数我们已经知道了肯定是(n-1)/(k-1)块了,所以可以直接想到放进优先队> 列,然后每次都拿前k个数,新的数继续丢进去

CODE:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>

using namespace std; 

#define LL long long
#define N 200100

LL a[N],T,n,t;
queue<int> q1, q2;

inline bool check(int x) 
    while(!q1.empty()) q1.pop();
    while(!q2.empty()) q2.pop();
    for(int i = 1 ; i <= n ; i++) 
        q1.push(a[i]);
    int num = 0;
    LL sum = 0,ans = 0;
    if((n - 1) % (x - 1) != 0) 
        num = (n - 1) % (x - 1) + 1;
        for(int i = 1 ; i <= num ; i++) 
            sum += q1.front();
            q1.pop();
        
        q2.push(sum);
        ans += sum;
    
    while(!q1.empty()) 
        sum = 0;
        for(int i = 1 ; i <= x ; i++) 
            if(!q1.empty() && !q2.empty()) 
                if(q1.front() <= q2.front()) 
                    sum += q1.front();
                    q1.pop();
                 else 
                    sum += q2.front();
                    q2.pop();
                
             else if(q1.empty())
                sum += q2.front();
                q2.pop();
             else if(q2.empty())
                sum += q1.front();
                q1.pop();
            
        
        ans += sum;
        q2.push(sum);
    
    if(ans > T) return false;
    sum = num = 0;
    while(!q2.empty()) 
        sum += q2.front();
        q2.pop();
        num++;
        if(num == x) 
            q2.push(sum);
            ans += sum;
            sum = num = 0;
            if(q2.size() == 1) break;
        
    
    if(ans > T) return false;
    else return true;


int main()  
    scanf("%lld",&t); 
    while(t--) 
        scanf("%lld%lld",&n,&T); 
        for(int i = 1 ; i <= n ; i++)
            scanf("%lld",&a[i]); 
        sort(a + 1, a + n + 1); 
        LL l = 2, r = n, mid, ans = 0; 
        while(l <= r) 
            mid = (l + r) >> 1; 
            if(check(mid)) 
                ans = mid;
                r = mid - 1;  
             else l = mid + 1; 
        
        printf("%lld\n", ans); 
    
    //system("pause");
    return 0; 

以上是关于Hdu 5884的主要内容,如果未能解决你的问题,请参考以下文章

hdu5884

HDU 5884 Sort (二分)

hdu5884 Sort

HDU 5884 Sort(二分+优先队列)

HDU 5884 Sort

HDU 5884 (贪心)