poj 3273

题目描述:

                n天分为m组,要求这m组尽可能每组钱数之和都很小,求所有分组方式里钱数之和最大的钱数。

题目类别:

               二分法应用。通过指定最大钱数之和判断组数是否符合要求,如果不符合,根据条件对low 和 high 进行赋值。

 

源代码:

#include<iostream>
#include<stdio.h>
using namespace std;

int n;   //天数
int m;   //组数   

bool Judge(int mid,int money[])  //判断当前组数是多还是少
{
	int i;
	int sum=0;
	int count=1;
	for(i=1;i<=n;i++)
	{
		if(sum+money[i]<=mid)    //钱数之和小于mid的可以算是一组内的
		{
			sum=sum+money[i];
		}
		else
		{
			sum=money[i];     //钱数之和大于mid要分两组
			count++;
		}
	}
	if(count>m)
		return false;   //组分多了,说明mid 较小
	else
		return true;
}

int main()
{
	int i;
	int low,high,mid;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		high=0;
		low=0;
		int *money=new int [n+1];
		for(i=1;i<=n;i++)
		{
			scanf("%d",&money[i]);
			high=high+money[i];     //上限是只分一组,即所有的数之和
			if(money[i]>low)  
				low=money[i];       //下限是分为n组,每天一组,取最大的   
		}

		mid=(low+high)/2;
		while(low<high)
		{
			if(Judge(mid,money)==false)   //mid值较小
				low=mid+1;
			else
				high=mid-1;
			mid=(high+low)/2;
		}
		cout<<mid<<endl;
		delete money;
	}
	return 0;
}

                  此题是二分法的另一种应用,以后类似题目皆可采用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值