Noip2015 普及组 推销员 题解

Noip2015 普及组 推销员 题解

今天老师叫我们参加提高组的同学都去做一下普及组的题目,前面3题都在比赛时就做出来了,只有第四题在比赛时没对,于是决定写一个题解。

题目描述

         阿明是一名推销员,他奉命到螺丝街推销他们公司的产品。螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户。螺丝街一共有 N 家住户,第 i 家住户到入口的距离为 S米。由于同一栋房子里可以有多家住户,所以可能有多家住户与入口的距离相等。阿明会从入口进入,依次向螺丝街的 X 家住户推销产品,然后再原路走出去。
         阿明每走 1 米就会积累 1 点疲劳值,向第 i 家住户推销产品会积累 Ai 点疲劳值。阿明是工作狂,他想知道,对于不同的 X,在不走多余的路的前提下,他最多可以积累多少点疲劳值。

输入

        第一行有一个正整数 N,表示螺丝街住户的数量。
         接下来的一行有 N 个正整数,其中第 i 个整数 Si 表示第 i 家住户到入口的距离。数据保证S1≤S2≤…≤Sn<108
         接下来的一行有 N 个正整数,其中第 i 个整数 Ai 表示向第 i 户住户推销产品会积累的疲劳值。数据保证 Ai<103

输出

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

对于 20%的数据,1≤N≤20;
对于 40%的数据,1≤N≤100;
对于 60%的数据,1≤N≤1000;
对于 100%的数据,1≤N≤100000。

 

20%的数据:随便搞搞

40%的数据:同上

 

60%的数据:枚举N次,每次枚举每一户人家,判断这一户人家是否被推销过,找到选择哪一户人家会得到最大的疲劳值,累加到ans里即可。注意:若选择在当前已选最靠右的一户人家(设为x)的左边的人家(设为y),则答案只需要增加推销这户人家的疲劳值(即ans=ans+A[y])。而选择x右边的人家(设为z),则答案需要增加多出来的走路疲劳值和推销这户人家的疲劳值(即ans=ans+(S[z]-S[x])*2+A[z])。时间复杂度O(n2)

 

100%的数据:和60分数据差不多,将枚举每一户人家改为用堆维护已选的最右边的那户人家(设为x)的左边推销疲劳值的最大值(设为堆D1)和x的右边推销疲劳值加上来回走路疲劳值的最大值(设为堆D2)。那么每次的答案就是ans=ans+max(D1[1],D2[1]-S[x]*2)。求答案之前要判断D1[1]和D2[1]是否合法(即D1[1]所对应的点在x左边且没选过,D2[1]所对应的点在x的右边且没选过)。时间复杂度O(n log2 n)。

你可能感兴趣的:(题解,堆)