Noip2015 普及组 推销员 题解
2015-11-14 16:00
239 查看
Noip2015 普及组 推销员 题解
今天老师叫我们参加提高组的同学都去做一下普及组的题目,前面3题都在比赛时就做出来了,只有第四题在比赛时没对,于是决定写一个题解。
题目描述
阿明是一名推销员,他奉命到螺丝街推销他们公司的产品。螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户。螺丝街一共有 N 家住户,第 i 家住户到入口的距离为 Si 米。由于同一栋房子里可以有多家住户,所以可能有多家住户与入口的距离相等。阿明会从入口进入,依次向螺丝街的 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)。
今天老师叫我们参加提高组的同学都去做一下普及组的题目,前面3题都在比赛时就做出来了,只有第四题在比赛时没对,于是决定写一个题解。
题目描述
阿明是一名推销员,他奉命到螺丝街推销他们公司的产品。螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户。螺丝街一共有 N 家住户,第 i 家住户到入口的距离为 Si 米。由于同一栋房子里可以有多家住户,所以可能有多家住户与入口的距离相等。阿明会从入口进入,依次向螺丝街的 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)。
相关文章推荐
- Metric learning 度量学习
- Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
- html/xml转excle
- onActivityResult不响应的情况分析和排查
- mac python install module
- ural 1243. Divorce of the Seven Dwarfs
- clscfg.bin: error while loading shared libraries: libcap.so.1:
- python文件读写总结
- C++迭代器的使用方法
- 06-ajax与页面和servlet的数据交互
- 绝缘子的故障处理
- android:descendantFocusability用法简析
- 酷狗界面仿照篇二
- LeetCode---Evaluate Reverse Polish Notation
- LaTeX制作中英文简历
- JAVA设计模式(21) —<行为型>访问者模式(Visitor)
- jQuery 1.9/2.0/2.1及其以上 on 无效的解决办法
- iOS 开发 git和代码时xib出现冲突的解决办法
- CMD查看进程ID并查杀进程
- xshell环境下vim编辑脚本右侧小键盘无法键入数字