题意:某个抠门的公司只有一个电梯, 现在有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;
}