BZOJ3419[POI2013]taxis——贪心
题目大意:
一条线段有三个点,0为初始位置,d为出租车总部位置,m为家的位置,人要叫车,有n辆车可以提供,每辆车有一个路程上限,并且都从车站出发,叫的车行驶之后不必须回到车站,问最少叫几辆车。
一定能想到的贪心策略是每次选最大的,但现在给这么一组数据:
12 4 5
2 3 4 5 8
发现先选最大的到不了m处了。
因为从出租车站到家只需要一辆车就够了,所以先选出比m-d大的车中路程上限最小的作为从车站到家的车,然后再贪心选最大的。
这里有几个细节要注意:
1、如果贪心选最大的的时候发现能直接到家,那么预留出来的车就没用了,要把答案减1。
2、预留出来的车可以先出车站一段去接人后再开往家。
#include<set> #include<map> #include<queue> #include<stack> #include<cmath> #include<bitset> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long using namespace std; ll m,d; int n; ll a[500010]; bool cmp(ll x,ll y) { return x>y; } ll mn; ll now; ll stop; int ans; int flag; int main() { scanf("%lld%lld%d",&m,&d,&n); for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); } sort(a+1,a+1+n,cmp); for(int i=1;i<=n;i++) { if(a[i]>=m-d) { mn=a[i]; flag=i; } } stop=d-((mn-(m-d))/2); ans++; for(int i=1;i<=n;i++) { if(i==flag) { continue; } if(a[i]<stop-now) { printf("0"); return 0; } if(now>=stop) { break; } now=a[i]-(d-now)+now; ans++; if(now>=m) { ans--; break; } } if(now<stop) { printf("0"); return 0; } printf("%d",ans); }