POJ 1505:二分枚举+贪心
二分枚举解空间+贪心判断解可行性的方法,适合很多形如求解Min{Max{…}}、Max{Min{…}}且具有单调性的问题。像:
POJ 1505 Copying Books 求:分配方案,使最后完成的时间最短。
POJ 1771 Elevator Stopping Plan 求:电梯停靠策略,使最后一个到达办公室的时间最短。
…
还有今年ICPC world final的Problem A (A Careful Approach) 求:飞机停靠方案,使得最短停靠时间间隔最大。
/**
* POJ 1505 Copying Books
* 算法:二分 + 贪心
*/
#include <cstdio>
#define N 501
typedef long long INT64;
int p[N];
int T,m,k;
INT64 min, max, mid;
bool isAssignOK()
{
int i, t = 1, sum = 0;
for(i = m - 1; i >= 0; --i)
{
if(sum + p[i] > mid) {
t++;
if(t > k)
return false;
sum = p[i];
} else
sum += p[i];
}
return true;
}
void print()
{
int i, j, t = 1, sum = 0;
bool e[N] = {false};
for(i = m - 1; i >= 0; --i)
{
if(sum + p[i] > max) {
t++;
sum = p[i];
e[i] = true;
} else
sum += p[i];
if(k - t == i + 1) {
for(j = 0; j <= i; ++j)
e[j] = true;
break;
}
}
for(i = 0; i < m - 1; ++i) {
printf("%d ", p[i]);
if(e[i])
printf("/ ");
}
printf("%d/n", p[m-1]);
}
int main()
{
int i;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &m, &k);
min = 0;
max = 0;
for(i = 0; i < m; ++i)
{
scanf("%d", p+i);
max += p[i];
min = (p[i] > min) ? p[i] : min;
}
while(min < max)
{
mid = (min + max) / 2;
if(isAssignOK())
max = mid;
else
min = mid + 1;
}
print();
}
return 0;
}
本文介绍了解决POJ1505CopyingBooks问题的方法,使用二分枚举与贪心算法结合的方式寻找最优解。通过二分搜索可能的最大完成时间,并用贪心策略检查分配方案是否可行,最终确定最小的最大完成时间。
2282

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



