bzoj 1555: KD之死 (贪心+STL)
Posted clover_hxy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1555: KD之死 (贪心+STL)相关的知识,希望对你有一定的参考价值。
1555: KD之死
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 99 Solved: 47
[ Submit][ Status][ Discuss]
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 64 2
2 3
Sample Output
2HINT
对于10%的数据,N<=10;
对于40%的数据,N<=100,W、T<=10000;
对于100%的数据,N<=600000,W、T<=2000000000;
注意事项:
数据很弱。
Source
题解:贪心+STL
考虑相邻两个的影响:如果at-bw>bt-aw,那么b放到a上比a放到b上更优。
因为b放到a上剩余的承重量更大。
那么我们可以按照at+aw从小到大排序,然后把车看成必选元素加入到最后。
我们现在插入的顺序是从上到下的放置顺序,即每次加入的放在最底层。然后将必选和不必选的分开考虑。
我们用一个大根堆维护目前加入的不必选的元素,这些元素是有可能被弹出的。
如果当前是必选元素,当前加入的所有元素的和超过了当前元素的承重量,那么我们就将堆中元素依次弹出,只到当前元素可以加入为止,如果堆空了还是无法加入,那么就无解
如果当前是不必选元素,能加入就直接加入,扔到大根堆中。如果加入不了就比较堆顶元素与当前元素w的大小,如果当前元素较小,并且只要弹出堆顶元素就可以加入,就将堆顶元素弹出,把当前元素加入。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#define N 1000003
#define LL long long
using namespace std;
int n,m,ans;
LL sum,tot;
priority_queue<LL> p;
struct data
LL w,t; bool flag;
bool operator <(const data &a) const
return w+t<a.w+a.t;
a[N];
int main()
freopen("a.in","r",stdin);
scanf("%d%d%lld",&n,&m,&tot);
for (int i=1;i<=n;i++) scanf("%lld%lld",&a[i].w,&a[i].t);
for (int i=1;i<=m;i++)
int x; scanf("%d",&x);
a[x].flag=1;
sort(a+1,a+n+1);
a[++n].w=0; a[n].t=tot; a[n].flag=1;
bool pd=true;
for (int i=1;i<=n;i++)
if (a[i].flag)
while (sum>a[i].t)
if (p.empty())
pd=false; break;
sum-=p.top(); p.pop(); ans--;
if (!pd) break;
sum+=a[i].w; ans++;
else
if (!p.empty()&&sum>a[i].t)
if (p.top()<a[i].w||sum-p.top()>a[i].t) continue;
if (!p.empty()&&sum>a[i].t) sum-=p.top(),p.pop(),ans--;
p.push(a[i].w); sum+=a[i].w; ans++;
if (!pd) printf("Foolish SD!");
else printf("%d\\n",ans-1);
以上是关于bzoj 1555: KD之死 (贪心+STL)的主要内容,如果未能解决你的问题,请参考以下文章