您的位置:首页 > 其它

poj 3273 Monthly Expense(二分)

2016-08-09 01:27 375 查看
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 5

100

400

300

100

500

101

400

Sample Output

500

题意: 给你天数N(1 ≤ N ≤ 100,000),和每天需要花的钱(存放在数组中),让你把这些天分成M(1 ≤ M ≤ N)份(每份都是连续的天),要求每份的和最大值尽量小,输出这个和。

思想:二分查找。让数组中的最大值为左界,数组的和为右界。左界的含义是将整个数组分成N块,那么和的最大值就是数组元素中的最大值。右界的含义是将整个数组当做一块,那么最大值就是所有数字之和。那么在左右界中(含左右界)的数肯定有一个是解。接着进行二分搜索:给定一个数count,从数组首元素开始叠加,超出count那么分块数i加1,那么这么遍历一遍后能得到以count为解所需的分块数,要是i小于M,说明count给的大了,反之count给小了。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m;
int a[100005];
int find(int temp)
{
int t=1,s=0;
for(int i=0;i<n;i++)
{
if(s+a[i]<=temp)
s=s+a[i];
else
{
s=a[i];
t++;
}
}
if(t<=m)
return 0;
else return 1;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
int low=0,high=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
high+=a[i];
if(low<a[i])
low=a[i];
}
int temp=(low+high)/2;
while(low<high)
{
if(find(temp))
low=temp+1;
else
high=temp-1;
temp=(low+high)/2;
}
printf("%d\n",low);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: