木棍切割问题(二分枚举)

题目描述

我们有n根的木棍。现在从这些木棍中切割出来m条长度相同的木棍,问这m根木棍最长有多长?

输入数据

第一行输入两个数字,n(1<=n<=1000)为木棍数目,m(1<=m<=1000)为需要切割出的相同长度的木棍数目 随后n个正整数,表示原始木棍的长度(<=10000)

输出数据

每组输出一行结果,表示切割后绳子的最长长度(保留两位小数)

样例输入
4 5
5 6 7 8
样例输出
4.00

分析

尝试遍历每一个切割长度l,如果每一根木棍的长度item/切割长度l之和大于等于m,即\sum item/l>=m,说明当前的切割长度l可以满足题意条件,找出满足条件的切割长度即可


本题中,我们的枚举对象是切割长度,因此可以采用二分枚举法,简化时间复杂度

代码

#include<iostream>
  #include<vector>
  using namespace std;

  int n=0,m=0;
  //检查切割长度mid是否满足条件
  bool check(vector<int> l,int mid)
  {
      int cnt=0;
      for(vector<int>::iterator it=l.begin();it!=l.end();it++)
      {
          int num=*(it)/mid;
          cnt+=num;
      }
      if(cnt<m)
          return false;
      else
          return true;
  }

  double sol(vector<int> l)
  {
      int lb=0,rb=10000+1;
      while(rb-lb>0.001)
      {
          int mid=(lb+rb)/2;
          if(check(l,mid))//说明当前切割长度还可以继续放大一点进行尝试是否满足条件
              lb=mid;
          else
              rb=mid-0.001;//说明当前切割长度不满足条条件,应当放小
      }
      return lb;
  }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值