POJ 3273-Monthly Expense(二分求最小和中的最大)

Problem Description

Farmer John is an astounding accounting wizard and has realized he might run out of money to run the farm. He has already calculated and recorded the exact amount of money (1 ≤ moneyi ≤ 10,000) that he will need to spend each day over the next N (1 ≤ N ≤ 100,000) days.

FJ wants to create a budget for a sequential set of exactly M (1 ≤ MN) fiscal periods called "fajomonths". Each of these fajomonths contains a set of 1 or more consecutive days. Every day is contained in exactly one fajomonth.

FJ's goal is to arrange the fajomonths so as to minimize the expenses of the fajomonth with the highest spending and thus determine his monthly spending limit.

Input

Line 1: Two space-separated integers: <i>N</i> and <i>M</i>< br>Lines 2..<i>N</i>+1: Line <i>i</i>+1 contains the number of dollars Farmer John spends on the <i>i</i>th day

Output

Line 1: The smallest possible monthly limit Farmer John can afford to live with.

Sample Input

7 5 100 400 300 100 500 101 400

Sample Output

500

//一个农夫为了避免农场倒闭,开始计划支出。现在有N天,每天都必须支出Mi元,现在要求把这N天分成M个月(每个月中必须是连续的天数),让我们来安排月份,使得每个月支出的钱最少。

就是求最小值里面的最大值,因为要满足每个月花费;

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <map>
using namespace std;
typedef long long LL;
const int inf=0x3f3f3f3f;
const double eps=1e-8;
const double pi= acos(-1.0);
const int maxn=100010;
int n,m;
int a[maxn];
int judge(int x)
{
    int i;
    LL sum=0,cnt=0;
    for(i=0;i<n;i++)
    {
        if(sum+a[i]<=x)
            sum+=a[i];//累加,若超出x则就生成新的一个月
        else
        {
            sum=a[i];//更新这个新的月的第一个值
            cnt++;//月份加1
        }
    }
    if(cnt>m)return 0;//太小
    return 1;//太大
}
int main()
{
    int high,low,mid;
    while(cin>>n>>m)
    {
        low=0;
        high=0;
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
            low=max(low,a[i]);
            high+=a[i];
        }
        while(low<=high)
        {
            mid=(low+high)>>1;
            if(judge(mid))
                high=mid-1;//太大,mid减小
            else
                low=mid+1;
        }
        cout<<mid<<endl;
    }

}

猜你喜欢

转载自blog.csdn.net/lanshan1111/article/details/81737529