「BZOJ1555」KD之死
Description
在F出去旅游的这几十年里面,地球上已经发生了翻天覆地的变化。原来KD早知道不和谐的地球即将会爆发有史以来的第一次SC(S**t Combat)大战,这场战争有可能毁灭地球,所以才强行推荐F去火星家园,以躲避这次战争。 战争发生的这些年间,KD带领的正义清扫军顽强抵抗,与敌人势均力敌,才让摇摇欲坠的地球得到残存。可惜世事难料,KD终是被奸人所害,让敌人从后方攻进基地,应对不及,身受重伤,奄奄一息。(日薄西山,气息奄奄。人命危浅,朝不虑夕。。。。。) SM(S**t Mother):哇嘎嘎嘎嘎嘎,天的光芒在照耀着我,你死定啦,地球就要毁灭啦。 但是SM没有发现,那个光芒是由F的拖拉机突破大气层时因摩擦产生火焰而发出的。在地球引力的加速下,拖拉机在X米高空处将F弹出后,碰巧飞速撞在了SM的身上。。。。。。SM惨叫一声后,就戏剧性的消逝了。虽然KD眼疾翅快,找了一个屏障,但毕竟是伤痕累累,受不住这么大的冲击,因此也圆寂了。。。。。。。。。 轰隆。。。KD和其他阵亡战士的躯体被装进了重重的GC里面,准备送往墓地。由于战争导致的科技极度退化,大家回到了板车时代。所以不得不将这些GC一个个竖着叠堆起来放在板车上,并由SD拖走。每个盒子都有一个重量W和它所能承受的最大重量T,即最多能有T单位重的盒子堆在它上面,否则会把它压烂,显然这个是不包括自身重量的。拖车虽然很顽强坚固,但是毕竟还是拖车,所以也还是有最大承受重量的。 因为和S混战了N久的SD也没多少力气了,所以他不想多次来回拖灵车,因此他只好每次拖运都装上尽量多的盒子。而且,还有更另SD抓狂的事:因为有些战士清扫功绩辉煌,所以必须在第一次拖运就将装他们的GC送往墓地。由于智商无限,SD想了半天都没想出来,无奈之下只好求助于过去世界的你,希望你告诉他第一次最多可以装多少个GC。
Input
第一行3个正整数N、M和MAXV,表示一共有N个GC,其中有M个GC必须在第一次运到墓地,拖车的最大承受重量是MAXV。 接下来N行每行2个正整数W和T,表示这个GC自身重量是W个单位,最大承受量是T个单位。 接下来M行每行一个正整数P,表示第P个输入的GC第一次必须运到墓地。
Output
一个正整数ANS,表示在满足要求的情况下,第一次最多能运多少GC到墓地。如果无法满足要求,请输出“Foolish SD!”。
Sample Input
2 0 6
4 2
2 3
4 2
2 3
Sample Output
2
HINT
对于10%的数据,N<=10;
对于40%的数据,N<=100,W、T<=10000;
对于100%的数据,N<=600000,W、T<=2000000000;
注意事项:
数据很弱。
Source
考虑俩个盒子A,B,显然若at-bw<bt-aw则将b放在下方较优
即at+aw<bt+bw时a一定只能放在b的上方
那么按照t+w排序后
维护大根堆贪心
顺序考虑每个盒子。
对于当前盒子,如果必须放,那么只要它放不了,就把已放的最重的盒子丢了(如果没有盒子可以丢就说明无解)。这个盒子因为不能丢,所以不入堆。
如果不必须放,那么能放就放。否则如果这个盒子比已放的最重的盒子轻,且丢掉最重的盒子后就能放了,那么把最重的盒子丢了,放这个盒子。如果这个盒子放了,就要把它放入堆中。 因为拖车不算盒子,所以答案是放了的总个数-1。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
#include<iostream> #include<cstring> #include<cstdio> #include<cstdlib> #include<algorithm> #include<queue> #include<cmath> #include<map> #include<queue> #define ll long long using namespace std; inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } ll tot,V; int n,m,w,ans; struct data{int w,t;bool f;}a[600005]; bool operator<(data a,data b) { return (unsigned int)a.w+a.t<(unsigned int)b.w+b.t; } priority_queue<int,vector<int> >q; void del() { tot-=q.top(); q.pop(); ans--; } void add(int x) { tot+=a[x].w; q.push(a[x].w); ans++; } bool solve() { tot=0; for(int i=1;i<=n;i++) { if(a[i].f==1) { while(tot>a[i].t) { if(q.empty())return 0; del(); } tot+=a[i].w;ans++; } else { if(!q.empty()&&tot>a[i].t) if(q.top()<a[i].w||tot-q.top()>a[i].t) continue; if(tot>a[i].t) del(); add(i); } } return 1; } int main() { n=read();m=read();V=read(); for(int i=1;i<=n;i++) { a[i].w=read();a[i].t=read(); } for(int i=1;i<=m;i++) { int x=read();a[x].f=1; tot+=a[x].w; } sort(a+1,a+n+1); a[++n].f=1;a[n].t=V; if(!solve())puts("Foolish SD!"); else printf("%d\n",ans-1); return 0; } |
Subscribe