hdu5884 Sort(二分)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Kirito_Acmer/article/details/52565138
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\n",l);
    }
    return 0;
}


没有更多推荐了,返回首页