POJ 3273 Monthly Expense(二分)

Monthly Expense
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 16813   Accepted: 6666

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

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天每天的花费,然后把这n天划分成m个消费月,要求消费月必须是连续的几天组成的(也可以是一天),求分成的m个月中,使每个月的消费和的最大值最小,输出这个最小的最大值。

最小化最大值,二分答案,求下限。

判断函数C(x)怎么写,参数x当然就是待检测的可能花费,只需要对n天从前往后用求和sum,大于x了就把之前的化成一个消费月,然后更新一下sum继续就好了。 如果某一天的消费都比x大,那么直接返回false就好了。

还有注意一下二分时区间的最大值的取值,不要取money的最大值10000,而应该是money*n=1000000000

/*
二分求下限 
*/
#include <stdio.h>
#include <string.h>

const int maxn=100000+10;
int n,m;
int a[maxn];

bool C(int x){
	int i,cnt=1,sum=0;
	for(i=0;i<n;i++){
		if(a[i]>x) return false;
		sum+=a[i];
		if(sum>x){	//如果>x了,这个月就可以停,并且i这一天要算到下个月里
			sum=a[i];
			cnt++;
		}
	}
	return cnt<=m;
}


int main()
{
	int i,max;
	while(scanf("%d%d",&n,&m)!=EOF){
		for(i=0;i<n;i++)
			scanf("%d",&a[i]);
		int l=-1,r=1000000000;
		while(r-l>1){
			int M=(l+r)/2;
			if(C(M))
				r=M;
			else
				l=M;
		}		
		printf("%d\n",r);
	}
	return 0;
}


你可能感兴趣的:(poj)