标签:queue sum iostream 分配 sam pac 效率 个数 ems
1、链接:
http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1039
2、题目:
Description
前段时间,某省发生干旱,B山区的居民缺乏生活用水,现在需要从A城市修一条通往B山区的路。假设有A城市通往B山区的路由m条连续的路段组成,现在将这m条路段承包给n个工程队(n ≤ m ≤ 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
3、解题分析:二分求解,分析时间的范围
最大时间:整条路由一个队来修
最短时间:修整路段中最长的一段路所用的时间,即耗时最长的工程队所用的时间
难点:
check()函数
判断遍历的路段的长度和前一个相加是否小于猜测的构造队伍最少花的时间
如果是就继续加
如果不是就从这个点重新累加
得到如果按这个预期算总共要用多少支队伍
如果得到的队伍数比给出的队伍数多了就代表预期短了,则扩大左区域,少了就代表比预期长了,则减小右区域
4、代码:
#include<iostream> #include<stdio.h> #include<algorithm> #include<string.h> #include<math.h> #include<queue> using namespace std; const int maxn = 305; int a[maxn]; int t, m , n; bool check(int t) { // printf("mid---------%d\n",t); int Ttmp = 0; int count = 1; for(int i = 0; i < m ; i++) { // printf("-----------\n"); if(Ttmp + a[i] <= t) { Ttmp += a[i]; } else { Ttmp = a[i]; count++; } // printf("Ttmp-----------%d\n",Ttmp); // printf("count-----------%d\n",count); } return count <= n; } int ans(int l ,int r) { int ans = r; while(l < r) { int mid = l + ((r - l) >> 1); if(check(mid))//为使时间尽可能的小,则右区间缩小 { ans = mid; r = mid ; } else { l = mid + 1; } } return ans; } int main() { scanf("%d",&t); while(t--) { scanf("%d%d",&m,&n); int Tsum = 0; int Tmax = 0; for(int i = 0; i< m ; i++) { scanf("%d",&a[i]); Tsum += a[i]; if(a[i] > Tmax) Tmax = a[i]; }int answer = ans(Tmax,Tsum); printf("%d\n",answer); } return 0; }
标签:queue sum iostream 分配 sam pac 效率 个数 ems
原文地址:http://www.cnblogs.com/hhkobeww/p/7831272.html