POJ 3273 Monthly Expense二分查找[最小化最大值问题]

POJ 3273 Monthly Expense二分查找(最大值最小化问题)

题目:Monthly Expense

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: 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.

思路:

1.先找出要二分的上下限,上限为所有天数花费的总和,下限为其中的最大话费,所要查找的最优解就在上限和下限之间

2.在上限下限之间进行二分,若得到的堆数大于题目所给的堆数,则应将mid+1赋值为下限,否则应将mid赋值为上限。

3.二分时得到堆数的判断,当总和大于mid时,堆数进行加一,而将总和重新进行赋值,否则总和一直相加,直到大于mid。

4.得到的下限或者上限即为最优解。

#include<stdio.h>
#include<iostream>
using namespace std;
int ans[100005]; 
int main()
{
    int N,M;
    scanf("%d%d",&N,&M);
	int sum=0,MAX=0;
    for(int i=0;i<N;i++)
    {
    	scanf("%d",&ans[i]);
    	sum+=ans[i];
    	MAX=max(MAX,ans[i]);
	}
	while(MAX<sum)
	{
		int mid=(MAX+sum)/2;
		int s=0,cnt=0;
		for(int i=0;i<N;i++)
		{
			s+=ans[i];
			if(s>mid)//此时的最优解为mid,因为MAX!=sum 
			//if(s>MAX)
			{
				cnt+=1;s=ans[i];
			}
		}
		if(cnt<M) sum=mid;
		else MAX=mid+1;
	}
	//跳出循环后 则MAX==sum 
	printf("%d
",sum);
    return 0;
}
原文地址:https://www.cnblogs.com/yyaoling/p/12260447.html