zoukankan      html  css  js  c++  java
  • hdu5884 Sort(二分)

    Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 547    Accepted Submission(s): 101


    Problem Description
    Recently, Bob has just learnt a naive sorting algorithm: merge sort. Now, Bob receives a task from Alice.
    Alice will give Bob N sorted sequences, and the i-th sequence includes ai elements. Bob need to merge all of these sequences. He can write a program, which can merge no more than k sequences in one time. The cost of a merging operation is the sum of the length of these sequences. Unfortunately, Alice allows this program to use no more than T cost. So Bob wants to know the smallest k to make the program complete in time.
     

    Input
    The first line of input contains an integer t0, the number of test cases. t0 test cases follow.
    For each test case, the first line consists two integers N (2N100000) and T (Ni=1ai<T<231).
    In the next line there are N integers a1,a2,a3,...,aN(i,0ai1000).
     

    Output
    For each test cases, output the smallest k.
     

    Sample Input
    1 5 25 1 2 3 4 5
     

    Sample Output

    3

    题意:给你n个数,以及花费m,要你找到最小的k,每次你可以把至多k个数合并成一个数,每次这样操作的花费是这些数的总和,要使得最后合成一个数后的代价不超过m。

    思路:先对整个a[]排序,二分k,然后用两个数组,第一个数组保存原来的a[]数组,第二个数组保存合并后的数,每次合并一个数后添加到这个数组的末位,每次取k个数是依次比较两个数组的头元素的大小,小的取出,直到取到k个数。这里要注意要先在a[]数组前补0,直到n补后%(k-1)==0.

    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    #include<string>
    #include<bitset>
    #include<algorithm>
    using namespace std;
    #define lson th<<1
    #define rson th<<1|1
    typedef long long ll;
    typedef long double ldb;
    #define inf 99999999
    #define pi acos(-1.0)
    #define Key_value ch[ch[root][1]][0]
    #define MOD 1000003
    #define maxn 100050
    int a[maxn],b[maxn];
    int n,m;
    int cal(int k)
    {
        int f2=1,r2=0,i;
        int f1,r1;
        int t=n%(k-1);
        int sum=0;
        for(i=1;i<=t;i++){
            sum+=a[i];
        }
        r2++;b[r2]=sum;
        r1=n;f1=t+1;
    
        int num=n/(k-1);
        int zong=sum;
        while(num--)
        {
            sum=0;
            for(i=1;i<=k;i++){
                if(f1>r1){
                    sum+=b[f2];
                    f2++;
                }
                else if(f2>r2){
                    sum+=a[f1];
                    f1++;
                }
                else{
                    if(a[f1]<b[f2]){
                        sum+=a[f1];
                        f1++;
                    }
                    else{
                        sum+=b[f2];
                        f2++;
                    }
                }
            }
            zong+=sum;
            if(zong>m)return 0;
            r2++;b[r2]=sum;
        }
        return zong<=m;
    }
    
    
    
    int main()
    {
        int i,j,T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            for(i=1;i<=n;i++){
                scanf("%d",&a[i]);
            }
            sort(a+1,a+1+n);
            int l,r,mid;
            l=2;r=n;
            while(l<=r){
                mid=(l+r)/2;
                if(cal(mid))r=mid-1;
                else l=mid+1;
            }
            printf("%d
    ",l);
        }
        return 0;
    }
    


  • 相关阅读:
    bzoj 2878: [Noi2012]迷失游乐园
    端口安全检查shell脚本
    Linux安全基线检查脚本
    kali修改时区
    Elasticsearch+Kibana+Logstash安装
    go基础语法
    windows server 2012泛域名解析配置
    域名解析知识总结
    DDOS防护原理
    kali 2.0下搭建DVWA环境
  • 原文地址:https://www.cnblogs.com/herumw/p/9464475.html
Copyright © 2011-2022 走看看