CF581E,JZOJ4689新车
来源:互联网 发布:linux tftp 搭建 编辑:程序博客网 时间:2024/04/27 08:31
题目描述
Keith家(多个)在城区,从城区到学校的路可以抽象成一个数轴,Keith家的坐标为W,学校的坐标为E。路上有很多加油站,每个加油站能提供92#,95#,98#三种汽油中的一种。由于Keith不缺钱,每到一个加油站,他都能加任意多的油。由于道路是双向的,Keith的车既能往左开,也能往右开。
1升汽油可以跑1千米,这与油的种类无关。车的油箱容量是S升,任何时候油箱中的油都不能超过S升,但是作为Keith大神的御用座驾,这台车有点与众不同,它的油箱中能同时存在多种汽油。出发时,油箱是装满98#汽油的。
众所周知的是,98#汽油最好,92#最差。由于Keith很爱惜自己的新车,所以他希望用尽可能少的92#汽油,如果有多种可能用的92#同样多,那就要求用的95#尽可能少。
现在Keith告诉你N个家的坐标Wi,学校的坐标E,以及路上所有加油站的坐标,求从各个家分别到学校的最优策略中,需要消耗的最少92#和95#汽油。
1 ≤ N , M ≤ 200000 , 0 ≤ Wi , Xi , E , S ≤ 10^9且Wi ≤ E , 1 ≤ Ti ≤ 3
分析
比赛的时候想到的贪心策略比较麻烦,没有简化,以致没法dp过去,而且那时候时间紧,暴力完后就赶紧想第一题了(也没写粗来···)。
首先把家和学校看成98加油站。然后贪心策略:从当前加油站出发,如果在s范围内有油品相同或者更好的,就走到最近的那个;如果没有,就尽量走远一点,并优先在油品比较好的加油站里停下加油,这里不一定加满。(当然不能停在另一个家)
然后设个f[i][0\1]表示在第i个加油站出发,此时车没油,要到达学校的所要用的92\95。从学校往左边跑就行了。
代码
#include<cstdio>#include<algorithm>using namespace std;#define fo(i,j,k) for(i=j;i<=k;i++)#define fd(i,j,k) for(i=j;i>=k;i--)const int N=2000005;struct rec{ int x,t,rev;}b[N];int e,s1,n,m,w[N],i,j,dur,s[4],d[4][N],f[N][2],ans[N][2],tt,tar,t[4];bool cmp(rec a,rec b){ return (a.x<b.x)||(a.x==b.x&&(a.t<b.t));}int main(){ freopen("car.in","r",stdin); freopen("car.out","w",stdout); scanf("%d %d %d %d",&e,&s1,&n,&m); fo(i,1,n) scanf("%d%d",&b[i].t,&b[i].x); b[n+1].x=e; b[n+1].t=3; tt=n+1; fo(i,1,m) { scanf("%d",w+i); b[++tt].x=w[i]; b[tt].t=4; b[tt].rev=i; } sort(b+1,b+1+tt,cmp); fo(i,1,tt) if (b[i].x==e&&b[i].t==3) { tt=i; break; } f[tt][0]=f[tt][1]=0; s[1]=s[2]=s[3]=1; t[1]=t[2]=t[3]=0; t[3]=1; d[3][s[3]]=tt; fd(i,tt-1,1) { if (b[i+1].x==b[i].x&&b[i].t<b[i+1].t&&b[i+1].t!=4) continue; fo(j,1,3) while (s[j]<=t[j]&&b[d[j][s[j]]].x-b[i].x>s1) s[j]++; tar=0; fo(j,min(b[i].t,3),3) if (s[j]<=t[j]&&(tar==0||b[d[j][t[j]]].x<b[d[tar][t[tar]]].x)) tar=j; if (tar) { f[i][0]=f[d[tar][t[tar]]][0]; f[i][1]=f[d[tar][t[tar]]][1]; if (b[i].t<3) f[i][b[i].t-1]+=b[d[tar][t[tar]]].x-b[i].x; } else { fd(j,3,1) if (s[j]<=t[j]) break; if (!j) { fo(j,1,i) f[j][0]=f[j][1]=-1; break; } f[i][0]=f[d[j][s[j]]][0]; f[i][1]=f[d[j][s[j]]][1]; if (b[i].t<3) f[i][b[i].t-1]+=s1; f[i][b[d[j][s[j]]].t-1]-=s1-(b[d[j][s[j]]].x-b[i].x); } if(b[i].t!=4) d[b[i].t][++t[b[i].t]]=i; } fo(i,1,tt) ans[b[i].rev][0]=f[i][0],ans[b[i].rev][1]=f[i][1]; fo(i,1,m) printf("%d %d\n",ans[i][0],ans[i][1]);}
反思
1,改题的时候太累了,改了一个小时,精神很重要。
2,贪心一定能简化就简化,这样写起来也容易点。
3,对于这个贪心不复杂的题目,大数据错就要多读程序,要在调试方法的耗时找个平衡点。
- CF581E,JZOJ4689新车
- 新车大灌篮
- 新车装饰的中国特色
- 哈哈哈我的新车
- 车检流程(非新车)
- 北京新车上牌指南
- 新车去异味妙招
- 新车上保险注意事项
- 【GDOI2017模拟8.12】新车
- [CF581 E]新车
- 买新车的注意事项/买新车需要注意什么?
- 041101买新车啦!爽。
- 新车磨合期保养完全攻略
- 我的新车常备用品
- 秀一下我的新车,hoho
- 公交车19路换新车啦,呵呵
- 赛拉图新车如何磨合及保养
- 新车拉高速的十个要领
- css公共样式
- 如何查看myeclipse的版本号?
- 关于UPnP Device Architecture 2.0的阅读笔记(七)
- UVA 1513 Movie collection
- linux学习第六课续
- CF581E,JZOJ4689新车
- java中length,length(),size()区别
- Linux安装redis扩展
- 虚构故事(1):Tomcat公司之恋
- 8583包中使用的压缩bcd
- 轻松一刻
- 263. Ugly Number
- 条件收敛中的黎曼定理 C语言
- JQuery(入门三)