poj 3273 Monthly Expense (二分搜索,最小化最大值)

题目:http://poj.org/problem?id=3273

思路:通过定义一个函数bool can(int mid):=划分后最大段和小于等于mid(即划分后所有段和都小于等于mid)

这样我们转化为求 满足该函数的 最小mid。即最小化最大值,可以通过二分搜索来做,要注意二分的边界。WR了好几次。

代码:

 

#include<iostream>

#include<string>

#include<cstdlib>

#include<cstdio>

using namespace std;

const int MAXN=100005;

int N,M,money[MAXN];

bool can(int mid)    //判断值 mid 是否满足划分M段后 每段最大和的最小值小于等于mid 

{

	int sum=0,cnt=0;

	for(int i=0;i<N-1;i++)

	{

		sum+=money[i];

		if(sum+money[i+1]>mid) {

			cnt++;

			sum=0;

		}

	}

	if(cnt>M-1)return 0;

	else return 1;

}

int main()

{

	while(cin>>N>>M)

	{

		int lhs=0,rhs=0;

		for(int i=0;i<N;i++)

		{

			scanf("%d",&money[i]);

			lhs=max(lhs,money[i]); //下届 

			rhs+=money[i];      //上届 

		}

		if(M==1) {

			cout<<rhs<<endl; // 不划分则输出所有元素的和 

			continue;

		}

		while(lhs<rhs)

		{

			int mid=(lhs+rhs)>>1;

			if(can(mid))rhs=mid;

			else lhs=mid+1;

		}

		cout<<lhs<<endl; 

	}

	return 0;

}


 

 

你可能感兴趣的:(exp)