【书本分发】

Description

You are given N number of books. Every ith book has Pi number of pages. You have to allocate books to M number of students. There can be many ways or permutations to do so. In each permutation one of the M students will be allocated the maximum number of pages. Out of all these permutations, the task is to find that particular permutation in which the maximum number of pages allocated to a student is minimum of those in all the other permutations, and print this minimum value. Each book will be allocated to exactly one student. Each student has to be allocated atleast one book.

 

Input

The first line contains 'T' denoting the number of testcases. Then follows description of T testcases:Each case begins with a single positive integer N denoting the number of books.The second line contains N space separated positive integers denoting the pages of each book.And the third line contains another integer M, denoting the number of studentsConstraints:1<= T <=70,1<= N <=50,1<= A [ i ] <=250,1<= M <=50,Note: Return -1 if a valid assignment is not possible, and allotment should be in contiguous order (see explanation for better understanding)

 

Output

For each test case, output a single line containing minimum number of pages each student has to read for corresponding test case.

 

Sample Input 1 

1
4
12 34 67 90
2

Sample Output 1

113

  此题可以想象成把数据按顺序装入桶中,M即是给定的桶数,问桶的容量至少应该为多少才能恰好把这些数装入M个桶中(按顺序装的)。

  首先我们可以知道,桶的容量最少不会小于数组中的最大值,即桶容量的最小值(小于的话,这个数没法装进任何桶中),假设只需要一个桶,那么其容量应该是数组所有元素的和,即桶容量的最大值;其次,桶数量越多,需要的桶的容量就可以越少,即随着桶容量的增加,需要的桶的数量非递增的(二分查找就是利用这点);我们要求的就是在给定的桶数量M的时候,找最小的桶容量就可以把所有的数依次装入k个桶中。

  值得一提的是,本题中并没有明确说明必须把书本按顺序连续分配给学生,否则12+90=102应该是sample1的最小值。如果不要求连续可以用最大堆来做。

/**
 * http://172.29.7.251/contest/19/problem/1-10
 * Created on 2020-12-28.
 * 找到最小的最大值
 */
import java.util.*;
public class BookDistribution {
    public static void main(String args[]){
        Scanner sc=new Scanner(System.in);
        int T=sc.nextInt();
        for(int i=0;i<T;i++){
            int n=sc.nextInt();
            int pages[]=new int[n];
            for(int j=0;j<n;j++){
                pages[j]=sc.nextInt();
            }
            int m=sc.nextInt();

            if(n<m){//有人分不到一本
                System.out.println(-1);
                continue;
            }
            System.out.println(makeBuckets(pages,m));

        }
    }

    static int getBuckets(int pages[],int buckets_max){
        int total=0;
        int buckets=1;//按当前桶的大小可以分几桶
        for(int i=0;i<pages.length;i++){
            total+=pages[i];
            if(total>buckets_max){//大于桶的最大值说明桶容量应该更大
                total=pages[i];
                buckets++;
            }
        }
        return buckets;
    }

    static int makeBuckets(int pages[],int m){
        int max=Integer.MIN_VALUE;//以数组中的最大元素作为最小的桶容量
        int sum=0;
        for(int i=0;i<pages.length;i++){
            max=Math.max(max,pages[i]);
            sum+=pages[i];
        }
        int low=max;
        int high=sum;
        //二分查找桶容量
        while(low<high){
            int mid=(low+high)/2;
            if(getBuckets(pages,mid)>m){//桶太小
                low=mid+1;
            }else{
                high=mid;
            }
        }
        return low;
    }

}

  参考链接https://www.cnblogs.com/ygh1229/p/10637504.html

posted @ 2020-12-28 21:14  A_Aron  阅读(426)  评论(0)    收藏  举报
//一下两个链接最好自己保存下来,再上传到自己的博客园的“文件”选项中