Getting half maximum 6 exercises to minimize the problem solution

Title Description

Before the invention of printing, copying a book is a very difficult job, a lot of work, but we need to actively cooperate to transcribe a book, teamwork is very important. At that time they are to be entered and copied books of the work by recruiting scribe, suppose now transcribe \ (m \) book, numbered \ (m, 2, 3 ... \) , each book has \ (1 \ le x \ le 100000 \) page, these books are assigned to \ (k \) a scribe, requires the number assigned to a scribe of those books must be continuous, each book can only be a scribe scribe. Each scribe speed is the same, your task is to find an optimal distribution plan so that all books under the premise can be copied finished, copyist at least each of the copied pages.

Input Format

In the first row, there are two integers \ (m and K,. 1 <= K, m <= 100000 \) . In the second row, there are \ (m \) integer \ (x_i \) separated by spaces. All of these values are positive and less than \ (100000 \) .

Output Format

Output line number that represents the best distribution scheme, all copying is completed, most of the pages copying copyist of the copied pages.

Sample input

9 3
100 200 300 400 500 600 700 800 900

Sample Output

1700

Topic analysis

This question involves algorithms: two.
Video explaining Address: https://www.bilibili.com/video/av59514881/?p=3
This question is half the answer.
First, we can write a bool check(int num)function to judge assigned to each scribe \ (num \) when the pages of the book \ (k \) a scribe whether the super-finished \ (m \) book. If you can, \ (the Check (NUM) \) return true; otherwise, \ (the Check (NUM) \) return false.
Then, we will find:

  • When \ (num = 0 \) when, \ (Check (0) \) certainly return false;
  • When \ (num = \ sum_ {i = 1} ^ nx_i \) when, \ (Check (\ sum_ {I} = ^ nx_i. 1) \) certainly return true, because the only one scribe can transcribe End \ (m \) book.

Then \ (0 \) and \ (\ sum_ {i = 1 } ^ nx_i \) must exist between a minimum \ (NUM \) such that \ (check (num) \) returns true.

we can find out:

  • If \ (check (num) \) to return true, then the \ (check (num + 1) , check (num + 2), ......, check (\ sum_ {i = 1} ^ nx_i) \) return true;
  • If (check (num-1) \ ) \ return false, then \ (check (num-2) , check (num-3), ......, check (0) \) return false.

So if we have to answer numas independent variables, the answer is to set up ( \ (the Check (NUM) \) results returned) as the dependent variable, we can get a monotonic function curve should be variable with independent variables change.

Codes are as follows:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int m, k;   // m表示书有多少本,k表示抄写员的数量
long long a[maxn];  // a[i]表示第i本书的页数
// check函数用于判断分配给没个抄写员num页书的时候能否超写完
bool check(long long num) {
    int id = 1;     // id用于标记当前抄写员的编号,一开始id=1
    long long tot = 0;  // tot用于表示第id个抄写员目前已经抄写的书的页数
    for (int i = 0; i < m; i ++) {  // 循环遍历每一本书
        if (num - tot >= a[i]) {    // 如果第id个抄写员能够抄写第i本书,
            tot += a[i];        // 将tot+=a[i],因为tot表示第id个抄写员目前抄写的书
        }
        else if (a[i] > num)    // 如果a[i]>num,说明任何抄写员都抄写不了第i本书
            return false;
        else {
            id ++;  // id++,变成下一个抄写员的编号
            tot = a[i]; // 更新下一个抄写员已经抄写的书的页数为a[i],因为他目前只抄写了第i本书
            if (id > k) return false; // 如果id>k,说明k个抄写员已经不够用了,直接返回false
        }
    }
    return true;    // 返回true
}
int main() {
    cin >> m >> k;
    long long sum = 0;
    for (int i = 0; i < m; i ++) {
        cin >> a[i];
        sum += a[i];
    }
    long long L = 0, R = sum, res; // L记录答案的左边界,R记录答案的右边界,res记录答案
    while (L <= R) {
        long long mid = (L + R) / 2LL;
        if (check(mid)) {   // 找到当前最优解
            res = mid;      // 更新答案
            R = mid - 1;    // 看看有没有更优解
        }
        else L = mid + 1;   // 进有半部分找解
    }
    cout << res << endl;    // 输出答案
    return 0;
}

Guess you like

Origin www.cnblogs.com/zifeiynoip/p/11450631.html