poj3273

利用二分法解决,重要的地方在于看出哪里是最大值和最小值。


题目大意:给定n个值,讲这些值分成m堆,要求找出分堆之后堆的最大值,然后

                从这些最大值中挑出最小值。


思路:刚开始想到的是,对这些值进行分堆,分成m堆后进行查找,但是在这一步上

          就不知道怎么写代码了,只好作罢。大神给的思路是二分,还是想了好久。。

          二分的优点是找出那个值,所以从这一点下手,想要找出最大值中的最小值,

          就得找到它的下限和上限。将所有的值分到一个组里,则这些数值的和就

          是上限,下限则是这些值中最大的那一个。因此,所求就在这个范围内,只

          要根据给出的m进行分堆,利用mid值则可以找到恰好能分成m堆的那个值,此

          时候,mid值即为所求了。


               二分法其实就是对所求数值下手,根据题目的要求进行不断的筛选,所以最大的

         要求体现在mid上,利用mid进行分堆然后判断。


#include <queue>
#include <stack>
#include <math.h>
#include <vector>
#include <limits.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <functional>
using namespace std;
#define N 100050
bool search(int n,int m,int mid,int data[])
{
     int i,group=1,sum=0;
     for(i=0;i<n;i++)
     {
          sum+=data[i];
          if(sum>mid)          //此时mid即为此次分类的最大值
          {
               sum=data[i];
               group++;
          }
     }
     if(group>m)
          return false;      //即是判断此时的mid是否符合要求
     else
          return true;
}
int main()
{
    int m,n,data[N],i,j;
    while(cin >> n >> m)
    {
         int high=0,low=0,mid;
         for(i=0;i<n;i++)
         {
            cin >> data[i];
            high+=data[i];
            low=low>data[i]? low:data[i];
         }
         mid=(low+high)/2;
         while(low<high)
         {
             if(!search(n,m,mid,data))
                  low=mid+1;
             else
                  high=mid-1;
             mid=(low+high)/2;
         }
         cout<<mid<<endl;
    }
    return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值