scau 数据结构 修剪树木

修剪树木

题目描述:

学校的环境优美,景色宜人,种植了很多绿化树。最近天气预报显示台风即将到来,为应对台风天气,学校近日组织开展专项绿化修剪工作,排查绿化树木存在的安全隐患,
修剪过长或枯萎树枝。现在已知总共需要修剪的树木数量 n n n(树木的序号为 1... n 1...n 1...n,按相邻的次序排列)以及每棵树修剪的耗费时间,学校打算安排m位工作人员来修剪树木,
为了提高工作效率避免来回跑动,每位工作人员安排修剪的树木一定是相邻的。为了保证能在台风到来前完成工作,负责人需要知道安排m位工作人员去修剪树木,最快需要多少时间就能完成修剪。

输入格式
Line 1: 两个用空格分开的整数n和m,分别表示需要修剪的树木总数和派出的工作人员数目, 1 ≤ m ≤ n ≤ 100 , 000 1≤m≤n≤100,000 1mn100,000
Lines 2…n+1: 第 i+1 行包含1个整数,表示修剪第i棵树需要的时间耗费 t i ( 1 ≤ t i ≤ 10 , 000 ) ti(1 ≤ ti ≤10,000) ti(1ti10,000),这n棵树按照相邻的次序排列

输出格式
Line 1: 输出最快能完成修剪所有树木的时间

输入样例

7 5
100
400
300
100
500
101
400

输出样例

500

提示
派出5个工作人员,第1个工作人员修剪第1、2两棵树(耗费时间为500),第2个工作人员修剪第3、4两棵树(耗费时间为400),第3个工作人员修剪第5棵树(耗费时间为500),
第4个工作人员修剪第6棵树(耗费时间为101),第5个工作人员修剪第7棵树(耗费时间为400),由于工作人员是同时工作的,所以最终总耗费时间500则可完成修剪任务.

思路:二分查找

时间复杂度:O(mlogN)

首先通过枚举可能的时间并判断是否符合条件,然后来确定本题最快能完成修剪所有树木的时间。但是一个一个枚举查找,时间复杂度太高,所以要优化。可以用二分查找的方法来优化,使得查找时间从O(N)-->O(logN)。其中N表示修建数目的时间范围本题的ti修建时间是 t i ( 1 ≤ t i ≤ 10 , 000 ) ti(1 ≤ ti ≤10,000) ti(1ti10,000)
其次就是二分查找的判断条件check函数了。check函数通过遍历工人,看在满足枚举的时间mid内能够最多修建多少颗树,如果修建的树的数量多于n棵,则表示满足条件,返回true,否则返回false。

不清楚二分查找或者二分查找不熟的,可以点击这个链接–>二分查找例题

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=1e5+10;
int n,m;
int a[N];
bool check(int mid)//mid表示枚举的可能的时间。
{
    int j=1;
    for(int i=1;i<=m;i++)
    {
        int t=mid;//把开始剩余的时间设成mid
        while(t>=a[j])//如果剩余的大于遍历到的那棵树的修剪需要的时间,就修剪该树。
        {
            t-=a[j];
            j++;
        }
        if(j>n+1)//如果修剪的树木的数量大于树木的总数,就表明成立
        {
            return true;
        }
    }
    return false;
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    int l=1,r=1e9;
    while(l<r)
    {
        int mid = (l + r) / 2;
        if(check(mid)) r=mid;
        else l=mid+1;
    }
    cout<<l;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值