用二分法进行分配。
假设 mid 就为所求的最小时间。
修路 | |||||
| |||||
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
1 #include<stdio.h> 2 int main() 3 { 4 int road[310]; 5 int t; 6 int n,m; 7 scanf("%d",&t); 8 while(t--) 9 { 10 int front=0,rear=0; 11 int i; 12 scanf("%d%d",&m,&n); 13 for(i=1;i<=m;i++) 14 { 15 scanf("%d",&road[i]); 16 rear+=road[i]; 17 if(road[i]>front) 18 front=road[i]; 19 } 20 int mid; 21 int tot,sum; 22 while(front<rear) 23 { 24 mid=(front+rear)/2; 25 for(i=2,tot=n-1,sum=road[1];i<=m;i++)//二分查找。 26 { 27 if(sum+road[i]>mid) 28 { 29 tot--; 30 sum=road[i]; 31 } 32 else sum+=road[i]; 33 } 34 if(tot<0) front=mid+1; 35 else rear=mid; 36 } 37 printf("%d\n",front); 38 } 39 return 0; 40 }
|