题意:有书需要被复印,连续m本需要划分给分给k个人进行复印,让每个人被分配的书的总页数的最大值最小,保证每个人至少被分配一本书。
题解:二分+贪心,先用二分把分配的总页数的最大值的最小值求出,然后用贪心从后往前划分,因为要求前面的人尽量工作量少。
#include <stdio.h>
#include <string.h>
const int N = 505;
int main() {
long long t, m, n, p[N], sum, x, mid;
scanf("%lld", &t);
while (t--) {
scanf("%lld%lld", &n, &m);
sum = x = 0;
for (int i = 0; i < n; i++) {
scanf("%lld", &p[i]);
sum += p[i];
}
while (x < sum) {
long long temp = 0, k = 1;
mid = (x + sum) / 2;
for (int i = 0; i < n; i++) {
temp += p[i];
if (p[i] > mid) {
k = m + 1;
break;
}
if (temp >= mid) {
temp = p[i];
k++;
if (k > m)
break;
}
}
if (k > m)
x = mid + 1;
else
sum = mid;
}
long long temp1 = 0, temp2 = 0, flag[N];
memset(flag, 0, sizeof(flag));
for (int i = n - 1; i >= 0; i--) {
temp1 += p[i];
if (temp2 < m - 1 && (temp1 > mid || i < m - 1 - temp2)) {//保证每个人至少分配一个
flag[i] = 1;
temp2++;
temp1 = p[i];
}
}
for (int i = 0; i < n; i++) {
printf("%lld", p[i]);
if (i != n - 1)
printf(" ");
if (flag[i])
printf("/ ");
}
printf("\n");
}
return 0;
}