题目来源:
题目大意:
将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;
}
本文介绍了一种使用二分法和贪心策略解决书本分配问题的方法。目标是将一系列页数不同的书分配给多个抄写员,使得整体抄写时间最短。通过设定抄写员能承担的最大页数范围,并采用从后向前的分组策略实现最优解。

1049

被折叠的 条评论
为什么被折叠?



