UVA_714
这个题目可以二分每个人分到的页数的上限,然后看能否安排成功并更新相应的max和min值,这样我们就得到了安排给每个人的页数的最大值的最小值。
题目要求输出一个安排方案,并且要求标号越小的人工作量越小,这一点我们可以用贪心策略来保证,只要让标号大的人分配到的工作量尽可能大即可。但同时要求每个人至少要有一本书的工作量,这一点可以在分配工作量时用一个判断,即剩下的书至少要等于劳动力的数量。
#include<stdio.h>
#include<string.h>
#define MAXD 510
int K, M, a[MAXD], p[MAXD][MAXD], num[MAXD];
void solve()
{
int i, j, k;
long long int min, max, mid, ans;
min = max = 0;
for(i = 0; i < M; i ++)
{
scanf("%d", &a[i]);
if(a[i] > min)
min = a[i];
max += a[i];
}
-- min;
for(;;)
{
mid = (max + min) / 2;
if(mid == min)
break;
ans = 0;
for(j = k = 0; j < M; j ++)
{
if(ans + a[j] > mid)
{
++ k;
if(k == K)
break;
ans = 0;
}
ans += a[j];
}
if(j == M)
max = mid;
else
min = mid;
}
ans = 0;
memset(num, 0, sizeof(num));
for(i = M - 1, k = K - 1; i >= 0;i --)
{
if(ans + a[i] > max || i == k - 1)
{
-- k;
ans = 0;
}
ans += a[i];
p[k][num[k] ++] = a[i];
}
for(i = 0; i < K; i ++)
{
for(j = num[i] - 1; j >= 0; j --)
{
if(i != 0 || j != num[i] - 1)
printf(" ");
printf("%d", p[i][j]);
}
if(i != K - 1)
printf(" /");
}
printf("\n");
}
int main()
{
int t;
scanf("%d", &t);
while(t --)
{
scanf("%d%d", &M, &K);
solve();
}
return 0;
}