UVA_714
这个题目可以二分每个人分到的页数的上限,然后看能否安排成功并更新相应的max和min值,这样我们就得到了安排给每个人的页数的最大值的最小值。
题目要求输出一个安排方案,并且要求标号越小的人工作量越小,这一点我们可以用贪心策略来保证,只要让标号大的人分配到的工作量尽可能大即可。但同时要求每个人至少要有一本书的工作量,这一点可以在分配工作量时用一个判断,即剩下的书至少要等于劳动力的数量。
#include#include #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; }