1023 修路 二分+模擬
題目描述
前段時間,某省發生乾旱,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
題目大意:就是m條路段承包給n個工程隊(n ≤ m ≤ 300),給出每一條路的長度,路多長就代表花多長時間來修這條路,可以有的工程隊不修路,但是不能有工程隊“跨路修路”,一條路只能給一個工程隊修,求修路最短時間
思路:修這m條路的最長時間就是所有的路段之和,最短時間就是m條路的最大值。然後把最小值到最大值之間的值二分模擬一下。在某個時間mid內,如果工程隊用完了,但是路還沒有修完,說明這個時間不滿足,應該low=mid+1;如果路修完了,但是工程隊還沒有使用完,那說明high=mid;
二分多想想邊界值
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cctype>
using namespace std;
int m,n;
int a[310];
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&m,&n);
int left = 0,right = 0 , mid;
for(int i = 0 ; i < m ; ++i){
scanf("%d",&a[i]);
if(left < a[i]) left = a[i];
right += a[i];
}
int use;
while(left < right){
use = 0;
mid = (left + right) /2;
int temp = 0;
for(int i = 0 ; i < m ; ++i){
temp += a[i];
if(temp > mid){
temp = a[i];
use++;
}
}
if(use <= n - 1){
right = mid;
}
else if(use > n-1){
left = mid+1;
}
}
printf("%d\n",left);
}
return 0;
}