【二分與三分03】Copying Books
阿新 • • 發佈:2019-01-26
題目來源:
題目大意:
將n本頁數為p1,p2,……,pm(順序排列)的書分給k個抄寫員抄寫,每個抄寫員速度一樣且每個抄寫員只能抄寫編號相鄰的書,求抄寫時間最少的分組。
解題思路:
二分法與貪心。
通過二分法求出一個抄寫員最多需要抄寫的頁數,然後按照這個頁數來分組,前面的組儘量分得多一點。
初始下界和上界是最後一本書的頁數和所有書的總頁數。
分組標記的時候從後往前找,之後還要檢查分完了沒,沒分完就繼續直到分完。
試過從前面開始找但總是出錯放棄了x
AC程式碼:
#include <stdio.h> #include <stdlib.h> #include <math.h> #define N 510 int n, k; int c[N]; int check(long long mid) { int i, j; long long num = 0; f = 0; for (i=0,j=0;i<n;i++) { num += c[i]; if (num>mid) { j++; i--; num = 0; } if (j==k) { if (i!=n-1) { return 0; } else { return 1; } } } return 1; } long long apart(long long l, long long r) { long long mid; while (l<r) { mid = (l+r)/2; if (check(mid)) { r = mid; } else { l = mid + 1; } } return r; } void print(long long r) { int flag[N] = {0}; int i, x=k; long long sum = 0; for (i=n-1;i>=0;i--) { sum += c[i]; if (sum>r) { i++; flag[i] = 1; x--; sum = 0; } } while (x>1) { for (i=1;i<n;i++) { if (!flag[i]) { flag[i] = 1; x--; break; } } } for (i=0;i<n;i++) { if (flag[i]) { printf("/ "); } printf("%d%c",c[i],i==n-1 ? '\n':' '); } } int main() { int T, i; long long sum, min; scanf("%d",&T); while (T--) { scanf("%d%d",&n,&k); sum = 0; for (i=0;i<n;i++) { scanf("%d",&c[i]); sum += c[i]; } min = c[i-1]; print(apart(min,sum)); } return 0; }