poj~3273(二分法)

poj3273

第一个做的二分法,以前一直以为二分法只能用在查找上,没想到二分那么神奇,还可以这样用。

该题的意思是:给你n个数,让你分成m分,要求分得各组的花费之和应该尽可能地小,然后输出花费最大的那组。


解题思路是,不断的二分这n组分成任意分的最大值,具体的还是看代码吧,详细在注释里。

#include <stdio.h>
#define MAX 100005

int n,m;


int check(int mid,int money[])
{
    int group=1,i;      //份数从1开始
    int sum=0;
    for(i=1;i<=n;i++)
    {
        if(sum+money[i]<=mid)
            sum+=money[i];
        else
        {
            group++;
            sum=money[i];
        }
    }
    if(group>m)         //分的组数太多,即mid太小 
        return 1;
    else
        return 0;
}
int main()
{
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        int  money[MAX];
        int i,low=0,high=0;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&money[i]);
            low=low>money[i]?low:money[i];      //当最多分成n份时,下界为所有数的最大值
            high+=money[i];                     //上界为所有数之和
        }
        int mid=(low+high)/2;
        while(low<high)             //不断二分找分成份数最靠近m的mid的最小值
        {
            if(check(mid,money))    //mid太小 ,即分的组数太多
               low=mid+1;
            else
                high=mid-1;
            mid=(low+high)/2;
        }
        printf("%d\n",mid);         //最后得出最合适的值mid
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值