UVALive - 2949 Elevator Stopping Plan

来源:互联网 发布:企业站seo 编辑:程序博客网 时间:2024/06/05 05:16
题意:有一个电梯,有n个人要上不同的目标层数,每个人可以选择搭电梯或走路,走路上一层或下一层都耗费20s,楼梯上一层要用4s,每次停下来持续10s,最后一个目标层数的停靠时间不计。要求设计一个电梯停靠计划,使得最后一个人到达他的目标层数所用时间最小,输出这个最小时间。思路:首先用二分查找时间,然后贪心这个时间是否满足所有的人,且尽量往高的地方去
#include <cstdio>#include <cstring>#include <iostream>using namespace std;int n, vis[35], i, sb, top, start, end, mid, open[35], num;void init() {    top = 1;     memset(vis, 0, sizeof(vis));    for (i = 0; i < n; i ++) {        scanf("%d", &sb);        vis[sb] = 1;        if (sb > top)            top = sb;    }    start = 0;     end = 14 * (top - 1);}int judge(int t) {    int i, j;    num = 0;    i = t / 20 + 2;      //在t时间内,t/20+2层以下的人可以走楼梯      while (i <= top) {    //每次把i作为最后一个人的目标楼层         while (i <= top && !vis[i])                i ++;        if (4 * (i - 1) + 10 * num > t)             return 0;        j = (t - 10 * num + 20 * i + 4) / 24;  //设在j层停,此时j>i,因为把i作为最后一个人的目标楼层,则满足等式t-10*num-4(j-1)-20*(j-i)=0          i = (t - 10 * num + 16 * j + 4) / 20 + 1;  //这时i为满足等式t-10*num-4(j-1)-20(i-j)=0的下一个楼层的位置,如果剩下的时间全都用来走路这是最坏的方法,也是下一个起点        open[num ++] = j;    }    return 1;}int solve() {    while (start < end) {        mid = (start + end) / 2;        if (judge(mid))            end = mid;        else            start = mid + 1;    }    return end;}int main() {    while (~scanf("%d", &n) && n) {        init();        printf("%d\n", solve());        judge(end);        printf("%d", num);        for (i = 0; i < num; i ++)            printf(" %d", open[i]);        printf("\n");    }    return 0;}



原创粉丝点击