您的位置:首页 > 运维架构

ZOJ 2002 Copying Books(二分答案)

2013-07-08 12:06 344 查看
最大值最优化问题, 二分答案.

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

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: