纪念属于自己的无尽深坑----hrbust修路

修路
Time Limit: 1000 MS Memory Limit: 65536 K
Total Submit: 771(317 users) Total Accepted: 417(287 users) Rating:  Special Judge: No
Description

前段时间,某省发生干旱,B山区的居民缺乏生活用水,现在需要从A城市修一条通往B山区的路。假设有A城市通往B山区的路由m条连续的路段组成,现在将这m条路段承包给n个工程队(≤ ≤ 300)。为了修路的便利,每个工程队只能分配到连续的若干条路段(当然也可能只分配到一条路段或未分配到路段)。假设每个工程队修路的效率一样,即每修长度为1的路段所需的时间为1。现在给出路段的数量m,工程队的数量n,以及m条路段的长度(这m条路段的长度是按照从A城市往B山区的方向依次给出,每条路段的长度均小于1000),需要你计算出修完整条路所需的最短的时间(即耗时最长的工程队所用的时间)。

Input

第一行是测试样例的个数T ,接下来是T个测试样例,每个测试样例占2行,第一行是路段的数量m和工程队的数量n,第二行是m条路段的长度。

Output

对于每个测试样例,输出修完整条路所需的最短的时间。

Sample Input

2

4 3

100 200 300 400

9 4

250 100 150 400 550 200 50 700 300

Sample Output

400

900

二分,写了很多次,最后总结一下所有路过的坑点

上下界:上界为总和,下界为最大值。

计数:如果初始为1,则不用考虑最后。如果初始为0,则考虑最后。

初始化:注意while内部的初始化!!!!!

#include<iostream>
#include<cstdio>
using namespace std;
#define INF 0x3f3f3f3f
long long a[100006];
int main()
{
    int n,m,T;
    cin>>T;
    while(T--)
    {
        cin>>n>>m;
        {
            long long maxnum=0;
            long long sum=0;
            for(int i=1; i<=n; i++)
            {
                cin>>a[i];
                maxnum=max(maxnum,a[i]);
                sum+=a[i];
            }
            long long l=maxnum,r=sum;
            long long now=0;
            long long need=0;
            while(l<=r)
            {
                now=0; ///两者初始化!!!!忘记很多次,坑了很多次,修路是心中的坑
                need=0;
                long long mid=(l+r)/2;
                for(int i=1; i<=n; i++)
                {
                    now+=a[i];
                    if(now>mid)
                    {
                        need++,now=a[i];
                    }
                }
                if(now)
                    need++;
                if(need>m)
                    l=mid+1;
                else
                    r=mid-1;
            }
            cout<<r+1<<endl;
        }
    }
}

其中,初始为0时(我自己常写的一种)

                now=0;
                need=0;
                long long mid=(l+r)/2;
                for(int i=1; i<=n; i++)
                {
                    now+=a[i];
                    if(now>mid)
                    {
                        need++,now=a[i];
                    }
                }
                if(now)
                    need++;

初始化为1时(其他人博客常写,但是一直没注意区别,导致浪费了很多时间)

            int temp = l[0];  
            int ans = 1;  
            for(int i=1;i<m;i++)  
            {  
                if(temp + l[i] >= mid)  
                {  
                    ans++;  
                    temp = l[i];  
                }  
                else  
                {  
                    temp += l[i];  
                }  
            }  
纪念一下,终于能彻底摆脱修路的坑了XD(希望是吧)

猜你喜欢

转载自blog.csdn.net/qq_41548233/article/details/80488475