您的位置:首页 > 其它

NOIP 2015 推销员

2016-11-02 20:40 274 查看
题目描述

阿明是一名推销员,他奉命到螺丝街推销他们公司的产品。螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户。螺丝街一共有N家住户,第i家住户到入口的距离为Si米。由于同一栋房子里可以有多家住户,所以可能有多家住户与入口的距离相等。阿明会从入口进入,依次向螺丝街的X家住户推销产品,然后再原路走出去。

阿明每走1米就会积累1点疲劳值,向第i家住户推销产品会积累Ai点疲劳值。阿明是工作狂,他想知道,对于不同的X,在不走多余的路的前提下,他最多可以积累多少点疲劳值。

【题目分析】

堆+贪心。

【代码】

#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;
struct node{int a,s,v,num;}b[100001];
struct cmp
{
bool operator ()(const node &a ,const node &b)
{return a.v<b.v;}
};
priority_queue <node,vector <node>,cmp> l,r;
int n,now=0;
int inl[100001],top=0;
bool cmp2(node a,node b)
{
return a.s<b.s;
}
int main()
{
long long ans=0;
scanf("%d",&n);
for (int i=1;i<=n;++i) scanf("%d",&b[i].s);
for (int i=1;i<=n;++i) scanf("%d",&b[i].a);
sort(b+1,b+n+1,cmp2);
for (int i=1;i<=n;++i) b[i].v=b[i].s*2+b[i].a,b[i].num=i;
for (int i=1;i<=n;++i) r.push(b[i]);
for (int i=1;i<=n;++i)
{
int tmp=-1,opt=-1;
while (!r.empty()&&r.top().s<now) r.pop();
if (!r.empty())
{
opt=1;
node x=r.top();
tmp=(x.s-now)*2+x.a;
}
if (!l.empty())
{
if (tmp<=l.top().a)
{
opt=0;
tmp=l.top().a;
}
}
ans+=(ll)tmp;
if (opt)
{
now=r.top().s;
inl[r.top().num]=1;
for (int i=top+1;i<r.top().num;++i)
if (!inl[i])
{
node x;
x.num=i;
x.a=b[i].a;
x.s=0;
x.v=b[i].a;
l.push(x);
inl[i]=1;
}
top=r.top().num;
r.pop();
}
else l.pop();
printf("%lld\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: