POJ - 3273 【二分】

Monthly Expense
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 32722   Accepted: 12294

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.

Source

[Submit]   [Go Back]   [Status]   [Discuss]

Home Page   Go Back  To top



All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di

Any problem, Please Contact Administrator

题意:有一个人破产了,要节省接下来几天的开支,他想到了一种办法,把连续的几天合并为一个月,问一个月的最大花费最小为多少?

这道题属于最大值最小化问题,可以和上一篇博客(最小值最大化)相对比,体会搜索边界的选取。

思路:二分答案为花费,保证连续几天的花费都小于二分值,如果大于,则改天另单独算作一个月。



#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define INF 0x3f3f3f3f  
using namespace std;
int a[1000010];
int n,m;
bool judge(int x){
	int sum=0,ans=1;
	for(int i=0;i<n;i++){
		sum=sum+a[i];
		if(sum>x){
			ans++;
			sum=0;
			i--;
		}
	}
	if(ans<=m) return true;
	else return false;
}
int main(){
	while(~scanf("%d%d",&n,&m)){
		int mind=-1,sum2=0;
		for(int i=0;i<n;i++){
			scanf("%d",&a[i]);
			mind=max(mind,a[i]);
			sum2=sum2+a[i];
		}
		int left=mind,right=sum2;
		int minn;
		while(right>left){
			int mid=(left+right)/2;
			if(judge(mid)){
				right=mid;//此题是最大值最小化问题,因为>=x的数不可能在mid
				//之后所以要缩小上界 
			}
			else {
				minn=mid;
				left=mid+1;
			}
		}
		printf("%d\n",left);
		//printf("%d\n",minn);
	}
	return 0;
}






猜你喜欢

转载自blog.csdn.net/xiang_hehe/article/details/80330790