题目

题目大意

阿明是一名推销员……螺丝街是一条直线,一端有入口,一共有 \(N(<100,000)\) 家住户,第 \(i\) 家住户到入口的距离为 \(S_i\) 米。由于同一栋房子里可以有多家住户,所以可能有多家住户与入口的距离相等。阿明会从入口进入,依次向螺丝街的 \(X\) 家住户推销产品,然后再原路走出去。

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

输入格式

第一行有一个正整数 \(N\),表示螺丝街住户的数量。

接下来的一行有 \(N\) 个正整数,其中第 \(i\) 个整数 \(S_i\) 表示第 \(i\) 家住户到入口的距离。 数据保证 \(S_1 ≤S_2 ≤…≤S_n <10^8\) 。

接下来的一行有 \(N\) 个正整数,其中第 \(i\) 个整数 \(A_i\) 表示向第 \(i\) 户住户推销产品会积累的疲劳值。数据保证 \(A_i <10^3\) 。

输出格式

输出 \(N\) 行,每行一个正整数,第 \(i\) 行整数表示当 \(X=i\) 时,阿明最多积累的疲劳值。

样例

样例输入

5
1 2 3 4 5
1 2 3 4 5

样例输出

15
19
22
24
25

分析Ⅰ

假设左边为入口,越往右越深,每个住户设为一个点。

“不走多余的路”,就是从最左端向右走到最右边的住户,再返回。所以\(X=1\)时,任意一个 \(i\) 点的疲劳值都为\(s[i]*2+a[i]\),选值最大的一个点即为答案。

假设你已经选了一些点,其中有一个最右端的点 \(now\),如果在其左方再选一个点 \(i\),推销员只要在路上“顺带”推销一下而无需增加行走路程,那么你选了这个点总疲劳值就增加 \(a[i]\)。

同理,在右边选一个点 \(j\),增加的疲劳值为 \(2*(s[j]-s[now])+a[j]\)。

于是,每次选择点时,取出左边疲劳值最大的点,枚举 \(now\) 右边的点找出边疲劳值最大的,两个比较,取大值。发现左边只要无脑取最大就好了,所以左边的点可以用堆维护。

如果左边的大,则直接弹出堆,否则将 \(now\)(最右点)更新,把 \(now+1...new\_now-1\) 之间的点的 \(a[i]\) 扔进堆里即可。时间复杂度,最好情况下是 \(O(nlogn)\),最坏情况下是 \(O(n^2)\),数据比较平均,所以能得满分。

代码Ⅰ(c++)

#include<cstdio>
#include<queue>
#define reg register
using namespace std;
priority_queue<int>ql; //左边的点
int n;
int a[100005],s[100005];
int main(){
scanf("%d",&n);
int xi=0,ans=0;
for(reg int i=1;i<=n;++i)scanf("%d",&s[i]);
for(reg int i=1;i<=n;++i)scanf("%d",&a[i]); for(int i=1;i<=n;++i)if((s[i]<<2)+a[i]>ans){
ans=(s[i]<<1)+a[i];
xi=i;
}
printf("%d\n",ans); //x=1时的解 for(int i=1;i<xi;++i)ql.push(a[i]); //左边扔进堆里
int now=xi; for(int i=2;i<=n;++i){
int lmax=0,rmax=0,ri=0;
if(!ql.empty())lmax=ql.top(); //左边最大
for(int j=now+1;j<=n;++j) if(((s[j]-s[now])<<1)+a[j] > rmax){
rmax=s[j]*2-s[now]*2+a[j]; //遍历右边找出最大
ri=j;
}
if(lmax>rmax){
ans+=lmax;
ql.pop(); //弹出堆
}else{
ans+=rmax;
for(int j=now+1;j<ri;++j)ql.push(a[j]); //左边扔进堆里
now=ri;
}
printf("%d\n",ans);
}
return 0;
}

分析Ⅱ

在Ⅰ的基础上,右边的点也用优先队列维护。

代码Ⅱ(c++)

#include <iostream>
#include <cstdio>
#include <queue>
#define MN 100005
#define R register
using namespace std;
int n,s[MN],a[MN];
int now,maxL,ans;
struct Node{
int num,tired;
bool operator<(const Node& a)const{return tired<a.tired;}
}node,maxR;
priority_queue<Node>qR;
priority_queue<int>qL;
inline int ri(){
char c=getchar();int x=0,w=1;
while(!isdigit(c)){if(c=='-')w=-1;c=getchar();}
while( isdigit(c)){x=(x<<3)+(x<<1)+c-48;c=getchar();}
return x*w;
}
int main(){
n=ri();
for(R int i=1;i<=n;i++)s[i]=ri();
for(R int i=1;i<=n;i++)a[i]=ri();
for(R int i=1;i<=n;i++)node.num=i,node.tired=2*s[i]+a[i],qR.push(node); //记个编号num
for(R int i=1;i<=n;i++){
maxL=maxR.tired=0;
if(!qL.empty())maxL=qL.top();
while(!qR.empty()&&qR.top().num<=now)qR.pop(); //弹出右边不符合要求的点
if(!qR.empty())maxR=qR.top();
if(maxL<maxR.tired-2*s[now]){
ans+=maxR.tired-2*s[now];
for(R int k=now+1;k<maxR.num;k++)qL.push(a[k]);
now=maxR.num;
qR.pop();
}
else ans+=maxL,qL.pop();
printf("%d\n",ans);
}
return 0;
}

【NOIP2015普及组】推销员_详解的更多相关文章

  1. [NOIP2015普及组]推销员

    题目:洛谷P2672.codevs5126.Vijos P1977 题目大意:有个推销员要去推销,要你求他推销1~n户人家分别最多花多少“疲劳值”.具体见题目. 解题思路:如果用$O(n^2)$做的话 ...

  2. 2019年CSP-J初赛试题(普及组)试题详解

    https://www.jianshu.com/p/9e58f455c1ee https://blog.csdn.net/weixin_39104847/article/details/1086711 ...

  3. NOIP2015普及组总结

    NOIP2015普及组总结 这次考试总体感觉不错,不过觉得时间有点紧,在最后30分钟才打完. 第一题(金币coin):大大的W!爆搜O(N),一分钟打完: 第二题(扫雷游戏mine):同上: 第三题( ...

  4. 线程组ThreadGroup分析详解 多线程中篇(三)

    线程组,顾名思义,就是线程的组,逻辑类似项目组,用于管理项目成员,线程组就是用来管理线程. 每个线程都会有一个线程组,如果没有设置将会有些默认的初始化设置 而在java中线程组则是使用类ThreadG ...

  5. [NOIP2015 普及组] 扫雷游戏

    [NOIP2015 普及组] 扫雷游戏 难度:入门 题目描述 扫雷游戏是一款十分经典的单机小游戏.在nn行mm列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格).玩家翻开 ...

  6. NOIP2015普及组第四题推销员

    好久没有写博客了,今天再写一篇.还是先看题: 试题描述 阿明是一名推销员,他奉命到螺丝街推销他们公司的产品.螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户.螺丝街一共有 N 家 ...

  7. 洛谷【P2669】NOIP2015普及组 T1金币

    我对模拟的理解:http://www.cnblogs.com/AKMer/p/9064018.html 题目传送门:https://www.luogu.org/problemnew/show/P266 ...

  8. shell-的特殊变量-进程状态变量$$ $! $? $_详解

    一:shell的特殊变量-进程状态变量详解  1. 进程状态变量 $$ 获取当前shell的进程号(pid) $! 执行上一个指令的pid,上一个后台运行进程的进程号 $? 获取执行上一个指令的返回值 ...

  9. NOIP2015普及组T4推销员(暴力+线段树)

    题目:阿明是一名推销员,他奉命到螺丝街推销他们公司的产品.螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户.螺丝街一共有N家住户,第i家住户到入口的距离为Si米.由于同一栋房子里 ...

随机推荐

  1. phpstudy2018 安装xdebug扩展

    第一步:查看PHP版本信息 第二步:到xdebug下载页去下载最新的版本(注意:要下载PHP对应版本) 第三步:把扩展php_xdebug-2.7.0alpha1-7.2-vc15-nts.dll放到 ...

  2. 利用dladdr来获得so自身的路径

    #include <dlfcn.h> //定义该函数为了dladdr获取符号信息 void fun1() { } Dl_info info; //dladdr获取某个地址的符号信息 int ...

  3. JMeter-生成性能测试结果报告

    1.将jmeter添加至环境变量,验证环境是否配置完毕: 终端输入jmeter,如果返回如下信息并启动jmeter说明环境已配置好了 2.修改配置文件 查找“Results file configur ...

  4. java的智能提示无法打开

    第一步:选中“window”->“preference”   第二步:选中“java”,并展开   第三步:选中“Editor”,并展开   第四步:选中“Content Assist”,在右侧 ...

  5. python装饰器扩展之functools.wraps

    我们知道函数被装饰器,装饰后,所有的属性,以及内置函数就失效了. 原因是函数类型变成了warpper类型 示例1:不带wraps装饰器示例 def warfunc(func): def warpper ...

  6. 《linux就该这么学》第十二节课:第10章,Apache网站服务

    第十章 10.1.网站服务程序 (让用户能够通过网站访问服务器上的资源) 目前提供的网站服务有IIS,Nginx,Apache等,IIS是windows中默认的web服务程序. Nginx是后起之秀, ...

  7. Yarn 组件的指挥部 – 调度器Scheduler

    linux基础 为hadoop集群的搭建扫清了障碍,也为内存的管理,文件系统的管理扫清了障碍 接着到Hadoop的阶段,首先做集群的安装,深入到使用这两个核心的组件,分布式文件系统HDFS,解决大量数 ...

  8. luogu P2327 [SCOI2005]扫雷

    很好的一道题,仔细思索(在y^3 dalao的帮助下)可以发现答案只有0 1 2三种情况 直接枚举第一位有没有雷,就可以递推了qwq 附上y^3大佬的blogs https://blog.csdn.n ...

  9. 【论文速读】ChengLin_Liu_ICCV2017_Deep_Direct_Regression_for_Multi-Oriented_Scene_Text_Detection

    ChengLin Liu_ICCV2017_Deep Direct Regression for Multi-Oriented Scene Text Detection 作者 关键词 文字检测.多方向 ...

  10. 从Redis中删除大集合对象的方法

    Redis中的大集合对象,如set.zset等,如果有上千万个元素,一般是不能直接用del命令来删除的,因为del命令可能会耗时几秒钟,而redis本身是单线程的,在高并发的情况下会阻塞大量的请求,严 ...