贪心+二分 openjudge746 Elevator Stopping Plan

题目描述了一个公司电梯使用的问题,要求用最短时间让所有人到达目标楼层。解决方案是采用二分查找结合贪心策略,二分查找最后一个人到达的时间,然后检查每个人能否在规定时间内通过电梯和爬楼梯到达目标。若能到达则继续,否则返回false。贪心策略是尽量将人送往高层,让他们走楼梯下楼以节省时间。代码实现过程复杂,调试困难。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:某个抠门的公司只有一个电梯, 现在有n 个人从1楼, 他们有各自想要

到达的楼层, 然后电梯每上一楼需要4 秒, 每在一个楼层开门需要10 秒, 

然后然爬楼梯的话需要20一楼。问, 如何用最短的时间让所有人都到达各自

想要到的楼层


题解:

如题,感觉以前做过的贪心题都弱爆了。。。这道题的思路是二分加贪心

二分最后一个到达的人的时间,那么这时,所有的问题就是判断这个时间

是否合法了,我们枚举每一个楼层(如果枚举电梯在哪个位置停是不全面的,

因为电梯有可能是在一个没有人的地方停,然后再让那个人下楼或上楼),

如果当前楼层有人,那么就判断一下,如果这个人能在限定时间内走到,就break

如果全靠坐电梯都不能在限定时间内到达,就return false,然后这时有一个

贪心策略,就是尽量把人往高处送,然后尽可能的让他走楼梯下到他要到达的楼层,

如果这样的话,想要到达的比电梯停的位置高的,时间并不会比在电梯直接在他

需要的楼层停长,而对于比到达的比电梯停的位置低的,时间肯定不会超过他


代码简直调得让我心力交瘁,调试效率太低了,花了一上午,最后调出来的代码也很丑

code:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>

const int MAXN=30005;
using namespace std;
int stop,cnt,n,top;
bool vis[MAXN];

inline int cal(){
	if(stop>=2) return (stop-2)*10;
	else return 0;
}
bool judge(int t){
    stop=1; int k=1;
    for(int i=1;i<=top;i++)
        if(vis[i])
        {
            if((i-k)*20+(k-1)*4+cal()<=t) continue;//如果能走楼梯
            if((stop-1)*10+(i-1)*4>t) return 0;//如果坐电梯都不行
            k=i+1;//如果能靠坐电梯满足,那么判断能否坐高点再走下来
            while(k<=top)
            {
                if((stop-1)*10+(k-1)*4+(k-i)*20<=t) k++;
                else break;
            }
            i=--k; stop++;
        }
    return 1;
}
int main()
{
    int l,r,mid;
    while(true)
    {
        scanf("%d",&n);
        if(!n) break;
        top=0; l=0x3f3f3f3f;
		memset(vis,0,sizeof vis);
		for(int i=1;i<=n;i++)
        {
            scanf("%d",&stop);
            top=max(stop,top);
            l=min(l,stop);
            vis[stop]=1;
        }
        l=(l-1)*4; r=(top-1)*14;
        while(l<r)
        {
            mid=(l+r)>>1;
            if(judge(mid)) r=mid;
            else l=mid+1;
        }
        printf("%d\n",l);
    }
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值