Los P1182 series valley segments Section II

Los P1182 series valley segments Section II

Luo Gu Portal

Title Description

For a given length is a positive integer number N of columns Ai Ai , want now divided into M (M ≦ N) M ( MN ) segments and each successive requirements, the minimum and maximum value of each segment, and .

About maximum minimum:

For example a series 4245142451 to be divided into 33 segments

Segment which is as follows:

[4 2][4 5][1][42][45][1]

And for the first section 66, para. 22 and 99, paragraphs 33 and 11, and a maximum of 99.

Segment which is as follows:

[4][2 4][5 1][4][24][51]

And the first section 44, para. 22 and 66, paragraphs 33 and 66, and a maximum of 66.

And in any case the segment, the maximum value of not less than 66.

To get the number of columns can be 4,245,142,451 to be divided into 33 segments, each of the maximum and minimum of 66.

Input Format

Line 11 comprises two positive integers N, M.

Line 22 contains N N spaces separated by non-negative integer A_i * A ** i *, as meaning the subject.

Output Format

A positive integer, that is how much each segment and maximum minimum.

Sample input and output

Input # 1 copy

Output # 1 copy

Description / Tips

20% to 20% of the data, there are n ≤ 10 N ≦ 10;

For the 40% to 40% of the data, there N≤1000 N ≤1000;

To 100% 100% of the data, there N≤100000, M ≦ N, A_i N ≤100000, MN , I ** * A * does not exceed 10 ^ 9109.

answer:

This question actually say is mathematically a bit, in fact, achieved when and P2882 and JDOJ 2225 is the same, (that is, the original title of the original code), I JDOJ 2225 explain the detail, so I used the solution to a problem JDOJ 2225 point of view it .

answer

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
int n,m,cnt,tot;
int l,r,ll,rr;
int a[maxn];
bool check(int x)
{
    tot=0;cnt=0;
    for(int i=1;i<=n;i++)
    {
        if(tot+a[i]<=x)
        {
            tot+=a[i];
            continue;
        }
        tot=a[i];
        cnt++;
    }
    if(tot>0)
        cnt++;
    if(cnt<=m)
        return 1;
    else
        return 0;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        ll=max(ll,a[i]);
        rr+=a[i];
    }
    l=ll;r=rr;
    while(l<r)
    {
        int mid=(l+r)/2;
        if(check(mid))//二分的答案域表示领到工资最多的那一次最小的工资额
            r=mid;
        else
            l=mid+1;
    }
    printf("%d",l);
    return 0;
}

Guess you like

Origin www.cnblogs.com/fusiwei/p/11468835.html