poj3273——典型的二分答案题目

来源:互联网 发布:淘宝贷款拖欠还款 编辑:程序博客网 时间:2024/05/08 12:54

Monthly Expense
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 24563 Accepted: 9550

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 ≤ M ≤ N) 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: N and M 
Lines 2..N+1: Line i+1 contains the number of dollars Farmer John spends on the ith day

Output

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

Sample Input

7 5100400300100500101400

Sample Output

500

Hint

If Farmer John schedules the months so that the first two days are a month, the third and fourth are a month, and the last three are their own months, he spends at most $500 in any month. Any other method of scheduling gives a larger minimum monthly limit.

题意:给出n个数,要求划分成m份,求每一份的总和的最大值的最小值,即最小化最大值,明显二分,即使二分不是很会,但是水水还是过了。

题解:即二分,二分答案的题目,首先必须有个判断答案是否正确的函数,下面代码为can(),然后在最小值答案和最大值答案之间进行二分,找到最小的答案,复杂度O(nlogn)。(最小值答案很明显就是分成n份的答案,最大值答案就是分成一份的答案)。

代码:

#include <cstdio>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#include <queue>#include <sstream>#include <fstream>#include <set>#include <map>#define INF 1e9#define M_PI 3.14159265358979323846using namespace std;int n,m;int s[100005];bool can(int a)//判断函数,判断最小值为a时能否分为m份{    int sum = 0,cnt = 0;    for (int i = 0;i < n;i++)    {        sum += s[i];        if(sum>a)        {            sum = s[i];            cnt++;        }    }    if(cnt+1>m)//当cnt+1比m大时,说明无法分成m份
        return false;    else        return true;}int main(){    //infile.open("1234.txt",ios::in);    while (cin>>n>>m)    {        int mos = 0,sum = 0;        for (int i = 0;i < n;i++){            cin>>s[i];            mos = max(mos,s[i]);            sum += s[i];        }        int lb = mos,ub = sum;        while(ub-lb>1)//二分查找        {            int mid = (ub+lb)/2;            if(can(mid)){                ub = mid;            }            else{                lb = mid+1;            }        }        if(can(lb)){            cout<<lb<<endl;        }        else            cout<<lb+1<<endl;    }    return 0;}


0 0
原创粉丝点击