POJ 1505:二分枚举+贪心

来源:互联网 发布:ue软件使用 编辑:程序博客网 时间:2024/05/17 23:49

POJ 1505:二分枚举+贪心

 

二分枚举解空间+贪心判断解可行性的方法,适合很多形如求解Min{Max{…}}、Max{Min{…}}且具有单调性的问题。像:

POJ 1505 Copying Books 求:分配方案,使最后完成的时间最短。

POJ 1771 Elevator Stopping Plan 求:电梯停靠策略,使最后一个到达办公室的时间最短。

还有今年ICPC world finalProblem A (A Careful Approach) 求:飞机停靠方案,使得最短停靠时间间隔最大。

 


/**  * POJ 1505 Copying Books * 算法:二分 + 贪心  */#include <cstdio>#define N 501typedef 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];} elsesum += 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;} elsesum += 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;}


原创粉丝点击