ZOJ 2002 Copying Books(二分答案)

来源:互联网 发布:java servlet destroy 编辑:程序博客网 时间:2024/06/06 09:50

最大值最优化问题, 二分答案.

每次二分的时候从后往前分配书即可满足条件.

#include <iostream>#include <cstdio>#include <memory.h>using namespace std;const int maxn = 510;long long P[maxn];bool Div[maxn], tmp[maxn];int N, K;int main(){int nCase;scanf("%d", &nCase);while (nCase--){long long l = 0, r = 0;scanf("%d%d", &N, &K);for (long long i = 0; i < N; ++i){scanf("%lld", &P[i]);r += P[i];}memset(Div, 0, sizeof(Div));while (l <= r){long long mid = (l + r) >> 1;memset(tmp, 0, sizeof(tmp));int i = N - 1, tk = K - 1, f = 0;for (; i >= 0 && tk >= 0; ){//从后往前分配.long long sum = 0;//当前人能够分到的最多数量int j = i;while(j >= 0 && sum <= mid && j >= tk){//要留下至少tk本书给剩下的tk个人if(sum + P[j] <= mid){sum += P[j--];}else{break;}}if(i == j)break;//第一本书就超过了mid,不可行i = j;if(i >= 0)tmp[i] = 1;--tk;}if(i >= 0){l = mid + 1;}else{memcpy(Div, tmp, sizeof(tmp));//更优的解r = mid - 1;}}for (long long i = 0; i < N; ++i){printf("%lld", P[i]);if(Div[i])printf(" / ");else if(i + 1 != N)printf(" ");}printf("\n");}return 0;}