codeforces 551C. GukiZ hates Boxes(二分+贪心)

一、题目概述

C. GukiZ hates Boxes
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Professor GukiZ is concerned about making his way to school, because massive piles of boxes are blocking his way.

In total there are n piles of boxes, arranged in a line, from left to right, i-th pile (1 ≤ i ≤ n) containing ai boxes. Luckily, m students are willing to help GukiZ by removing all the boxes from his way. Students are working simultaneously. At time 0, all students are located left of the first pile. It takes one second for every student to move from this position to the first pile, and after that, every student must start performing sequence of two possible operations, each taking one second to complete. Possible operations are:

  1. If i ≠ n, move from pile i to pile i + 1;
  2. If pile located at the position of student is not empty, remove one box from it.

GukiZ's students aren't smart at all, so they need you to tell them how to remove boxes before professor comes (he is very impatient man, and doesn't want to wait). They ask you to calculate minumum time t in seconds for which they can remove all the boxes from GukiZ's way. Note that students can be positioned in any manner after t seconds, but all the boxes must be removed.

Input

The first line contains two integers n and m (1 ≤ n, m ≤ 105), the number of piles of boxes and the number of GukiZ's students.

The second line contains n integers a1, a2, ... an (0 ≤ ai ≤ 109) where ai represents the number of boxes on i-th pile. It's guaranteed that at least one pile of is non-empty.

Output

In a single line, print one number, minimum time needed to remove all the boxes in seconds.

Examples
input
2 1
1 1
output
4
input
3 2
1 0 2
output
5
input
4 100
3 4 5 4
output
5
Note

First sample: Student will first move to the first pile (1 second), then remove box from first pile (1 second), then move to the second pile (1second) and finally remove the box from second pile (1 second).

Second sample: One of optimal solutions is to send one student to remove a box from the first pile and a box from the third pile, and send another student to remove a box from the third pile. Overall, 5 seconds.

Third sample: With a lot of available students, send three of them to remove boxes from the first pile, four of them to remove boxes from the second pile, five of them to remove boxes from the third pile, and four of them to remove boxes from the fourth pile. Process will be over in 5 seconds, when removing the boxes from the last pile is finished.

二、题目释义

从左到右有 n 个 pile 每个 pile 里面有不定数量的 boxes 在最左边的 pile 的左边有m个学生要为老师来搬箱子,它们每个人有两种行动策略,向右移动一格,或者搬走一个当前 pile 下的箱子,每种策略都需要一秒钟,问你把所有箱子搬完所需的最短时间

三、思路分析

我们容易想到去二分所需的时间,如果这个时间下所需的学生比 m 小,则二分的时间要减,否则要加。关键在于设计贪心策略,这里仅给出一种可行的设计方案(有非常多的思考方向),设所需的时间为 x ,那么学生花在路上的时间为 i ,那么他可以拿来搬箱子的时间即为 x-i ,不断向右推进,记录箱子的总数sum,也是搬掉这些箱子所要的时间,当 sum >= x 我就需要派出一个学生 则 sum -= x-i 我们能使用的学生数 - 1 

四、AC代码

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;
typedef long long LL;
const int N = 1e5+5;

int a[N];
int n,m,flag;

bool check(LL x)
{
    int cnt = m;
    LL sum = 0;
    for(int i=1; i<=flag; i++)
    {
        sum += a[i];
        while(sum+i >= x)
        {
            sum -= (x-i);
            cnt--; 
            if(cnt<0) return 0;
        }
    }
    if(cnt==0) return sum <= 0;
    return 1;
}

int main()
{
    LL l,r,mid;
    l = 0, r = 0;
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        r += a[i];
    }
    for(int i=n; i>=1; i--)
    {
        if(a[i])
        {
            flag = i;
            break;
        }
    }
    l = flag+1; r += flag;
    while(r-l>=1)
    {
        mid = (l+r) / 2;
        // cout << l << " " << mid << " " << r << endl;
        if(check(mid)) r = mid;
        else l = mid+1;
    }
    // cout << l << " " << mid << " " << r << endl;
    printf("%I64d
",r);
    return 0;
}