uvalive 2949 - Elevator Stopping Plan(贪心+二分)

题目连接:2949 - Elevator Stopping Plan


题目大意:某个抠门的公司只有一个电梯, 现在有n 个人从1楼, 他们有各自想要到达的楼层, 然后电梯每上一楼需要4 秒, 每在一个楼层开门需要10 秒, 然后然爬楼梯的话需要20一楼。问, 如何用最短的时间让所有人都到达各自想要到的楼层。


解题思路:因为人可以爬楼梯, 所以可以在某个楼层下楼之后走楼梯到达想要到的楼层, 只要在最后一个人到达之前就可以。 对于时间可以采取二分的方式搜索, 所以只要判断某个时间能否将所有人送到指定楼层就可以了。 对于判断我们可以用贪心去做, 尽量让电梯停在较高的楼层,只要剩余的时间够使得人走到自己的楼层就可以了。


#include <stdio.h>
#include <string.h>
const int N = 32;

int n, mid, top, cnt, vis[N], stop[N];

void read() {
    int t;
    top = 0;
    memset(vis, 0, sizeof(vis));

    for (int i = 0; i < n; i++) {
	scanf("%d", &t);
	vis[t] = 1;
	if (t > top)	top = t;
    }
}

bool judge(int tmp) {
    cnt = 0;
    memset(stop, 0, sizeof(stop));

    for (int i = tmp / 20 + 2; i <= top; i++) {
	while (!vis[i] && i < top)  i++;
	int t = (i - 1) * 4 + cnt * 10;
	if (tmp < t)	return false;
	t = (tmp - 10 * cnt + 20 * i + 4) / 24;
	i = (tmp - 10 * cnt + 16 * t + 4) / 20;
	stop[cnt++] = t;
    }
    return true;
}

int solve() {
    int L = 0, R = 14 * (top - 1);
    while (L < R) {
	mid = (L + R + 1) / 2;
	if (mid == R)	break;
	if (judge(mid))
	    R = mid;
	else
	    L = mid;
    }
    return mid;
}

int main() {
    while (scanf("%d", &n) == 1 && n) {
	read();

	judge(solve());

	printf("%d\n%d", mid, cnt);
	for (int i = 0; i < cnt; i++)
	    printf(" %d", stop[i]);
	printf("\n");
    }
    return 0;
}

你可能感兴趣的:(uvalive 2949 - Elevator Stopping Plan(贪心+二分))