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;
    }
    


  • 相关阅读:
    动态加载js文件并且执行回调方法
    二分查找法查找数组元素下表
    用横线隔开字符串
    不要再拖别人的控件2.帮前面的东东加个事件
    IE6 外部样式引用不进来
    用jQuery+css+div 写一个 乱换效果
    不要再拖别人的控件3.为什么要学习.net控件开发
    带一键还原的FTP上传软件
    .net 四舍六入 五成双
    Fiddler实战之请求头(request headers)和响应头(response headers)
  • 原文地址:https://www.cnblogs.com/herumw/p/9464475.html
Copyright © 2011-2022 走看看