The use of unconventional dichotomy was also made in Lintcode today, and it was felt necessary to record it.
Test instructions
gives an array a containing n elements, representing n books and their respective number of pages. Now there is a K personal copy books, each person can only copy a serial number of books, such as a[1],a[2] by the first person to copy, but not a[1],a[3] by the first person to copy, for the minimum time required to copy all the books.
Examples:
A = [3,2,4],K = 2 returns 5, the first person copies the first two books
The problem looks very difficult to look at, but in fact, the problem is very simple, is a two-part legal interval of the problem. Before that, I also wrote two blogs about the use of unconventional dichotomy, which are relatively similar.
1. Solving ideas
First, we assume that only one person is copying a book, then the time to use is the sum of all the pages of the book, we assume that sum, if there are countless people in the copy of the book (in fact, we consider the number of books and the number of equal, not the page of the book), then the use of time is the maximum pages I assume it's max. Therefore, we conclude that the K-man in the copy of the book, the use of time must be [Max, sum].
Therefore, we can continue to narrow the scope of the [max,sum] in the interval of two points. The method is this, we calculate the MID = (start + end)/2 (assuming start = max, end = SUM), and then calculate the number of people needed when the maximum page size is mid, we assume count, if Count is greater than K, then if the K personal copy M The ID page is not enough, if you need to increase the number of copies of each person (the number of pages must be in (Mid, end), so start = mid; instead, it means that everyone copies the mid page is more printed, the K person can not need to print, so we need to reduce the number of copies of each person ( This page must be in [Start,mid]).
But there is a problem here, which is the end of the two-point condition. The previous two-point end condition is almost always start < end, but it's not the same here, because if you end up like that, then there's a possibility of a dead loop. For example:
Therefore, the end condition of the two points here cannot be set to start < Mid, which should be start + 1 < mid. At the end of the calculation, if, in the case of start, Count <= K, the start is returned, and the inverse returns end.
2. Code
1 Public Static intCopybooks (int[] pages,intk) {2 if(pages =NULL|| Pages.length = = 0 | | K = = 0) {3 return0;4 }5 6 intMax =Integer.min_value;7 intsum = 0;8 //calculate maximum and Sum9 for(inti:pages) {Ten if(I >max) { OneMax =i; A } -Sum + =i; - } the intStart =Max; - intEnd =sum; - //two points - while(Start + 1 <end) { + intMid = (End-start)/2 +start; - + if(Countcopier (pages, mid) >k) { AStart =mid; at}Else { -End =mid; - } - } - returnstart; - } in //calculate the number of people needed to copy limit pages in each person - Private Static intCountcopier (intPages[],intlimit) { to intsum = pages[0]; + intCopiercount = 1; - for(inti = 0; i < pages.length; i++) { the if(sum + pages[i] >limit) { *copiercount++; $sum = 0;Panax Notoginseng } -Sum + =Pages[i]; the } + returnCopiercount; A}
Algorithm-book copy (dichotomy)