好久没有写博客了,今天再写一篇。还是先看题:

试题描述
阿明是一名推销员,他奉命到螺丝街推销他们公司的产品。螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户。螺丝街一共有 N 家住户,第 i 家住户到入口的距离为 Si 米。由于同一栋房子里可以有多家住户,所以可能有多家住户与入口的距离相等。阿明会从入口进入,依次向螺丝街的 X 家住户推销产品,然后再原路走出去。阿明每走 1 米就会积累 1 点疲劳值,向第 i 家住户推销产品会积累 Ai 点疲劳值。阿明是工作狂,他想知道,对于不同的 X,在不走多余的路的前提下,他最多可以积累多少点疲劳值。
输入
第一行有一个正整数 N,表示街住户数量,接下来一行有 N 个正整数,其中第 i 个整数 Si 表示第 i 家住户到入口距离保证 S1<=S2<=S3....<10 的 8 次方。接下来一行有 N 个整数,其中第 i 个整数 Ai 表示向第 i 个住户推销产品会积累疲劳值。保证 Ai<=10 的 3 次方。
输出
输出 N 行,每行一个正整数,其中第 i 行整数表示当 x=i,阿明积累的疲劳值。
输入示例
5
1 2 3 4 5
1 2 3 4 5
输出示例
15
19
22
24
25
其他说明
数据范围:1<= N <= 1000000。

针对每一个X,我在考场当时想能不能用贪心,每一次都选取当前那一个疲劳值最大的房子,但不知怎么了,认为不行,觉得应该用DP做,然后就当场懵逼了。现在想何尝不可以呢?证明很简单,只要用反证法即可。注意,题目中所说不走多余路的意思就是推销x的房子的时候必须一口气走完,不能绕来绕去,这样就更能说明了这样的贪心策略是可以的。本题为去年普及组最后一题,当时没做出来,现在就秒杀了,感觉自己有很大进步。

贪心策略想好了,下面就开始实现,如何选取当前那一个疲劳值最大的房子呢?对于一个没来过的房子(偏向右端),价值就是s[i]*2+a[i],这里指的是第一个,接下来就不一样了,每一次接下来选择的都是阿明走过最远房子的左端或右端中价值最大的房子。对于左端,因为不能走多余的路,所以价值就是a[i],右端呢,需要加上往返的距离,所以价值就是a[i]+(s[i]-now)*2,其中now指的就是阿明走过最远房子的位置,然后取一个最大值即可。如何快速找呢?很容易就能想到可以用一个最大堆来实现,就用STL里的priority_queue实现了,优先队列要声明两个,一个维护now左端的房子,另一个维护now右端的房子。注意开始时now=0;

想这么多就差不多可以开始写了,首先我先无脑写了一个结构体node,里面包含着四种信息(编号,a[i],s[i],价值),然后就把结构体读入了,但是到后来才知道:价值是会变的,在读入中盲目就读入价值是不行的……之后终于写完了,提交到oj上,结果时间超限,多交了几次,有一回999ms卡过了,我就意识到应该是读入的问题,于是就把scanf改成了read,然后就AC了。

下面是代码:

 #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=;
int n,flag[maxn],ans,s[maxn],a[maxn],now;
struct node{
int s,val,num;
bool operator < (const node &b)const //重载运算符,目的是帮助优先队列排序
{
if(val!=b.val)return val<b.val;
return s<b.s;
}
};
node MAX(node a,node b){return a<b ? b :a;}
int read()
{
int x = , f = ; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -; c = getchar(); }
while(isdigit(c)){ x = x * + c - ''; c = getchar(); }
return x * f;
}
int main()
{
priority_queue <node> Q1,Q2;
n=read();
for(int i=;i<=n;i++)s[i]=read();
for(int i=;i<=n;i++)
{
a[i]=read();
Q2.push((node){s[i],a[i]+s[i]*,i});//由于初始位置是now,所以把所有都加入Q2,表示在右端
}
for(int i=;i<=n;i++)
{
node t1=(node){,,},t2=(node){,,};
if(Q2.size())
{
t1=Q2.top();Q2.pop();
while(t1.s<=now && Q2.size())t1=Q2.top(),Q2.pop();//把Q2中位于now左边的都删了
t1.val-=*now;
}
if(Q1.size())t2=Q1.top(),Q1.pop();
node t0=MAX(t1,t2);
if(t0.num==t2.num && t1.num)t1.val+=*now,Q2.push(t1);//注意在搁回Q2时,不要忘记将点权在加回2*now
else if(t0.num==t1.num)Q1.push(t2);//选取t0的操作是选取now左端和右端的点权最大值,在选取之后务必要把那个没有被选上的房子搁回队列中,要不就无视那房子了
flag[t0.num]=;
ans+=t0.val;
printf("%d\n",ans);
if(t0.s>now)
{
now=t0.s;
for(int j=;j<=t0.num;j++)//将位于now左边的全部加入Q2
if(!flag[j])
Q1.push((node){s[j],a[j],j});
}
}
return ;
}

调了很久才叫真正AC。

有几处小细节,是我在研读他人代码时发现的,我自己编的数据是这样的:

5

1 2 3 4 5

10 10 10 20 2

以及它的对称:

5

1 2 3 4 5

2 20 10 10 10

就是因为这两组数据卡爆了多少人,其中包括幸京睿,汪梁森,还有王子健。(然而李琦煜和吕紫剑的程序能完美解决这个问题)问题主要是出在第48,49行代码上,具体意思请看旁边注释。由此可见,小细节还是十分坑爹的,关于如何解决这些问题的话,还是要多做题吧。

在这里我来吐槽一下NOIP普及组给的测试数据究竟有多水,本人在之前有N多个bug的前提下仍旧AC了!!

NOIP2015普及组第四题推销员的更多相关文章

  1. 洛谷 P1070 道路游戏(noip 2009 普及组 第四题)

    题目描述 小新正在玩一个简单的电脑游戏. 游戏中有一条环形马路,马路上有 nn个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针顺序依次将这 nn个机器人工厂编 ...

  2. NOIP2015普及组总结

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

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

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

  4. NOIP2005普及组第4题 循环

    NOIP2005普及组第4题 循环 时间限制: 1 Sec  内存限制: 128 MB提交: 27  解决: 6[提交][状态][讨论版][命题人:外部导入] 题目描述 乐乐是一个聪明而又勤奋好学的孩 ...

  5. NOIP2005普及组第3题 采药 (背包问题)

    NOIP2005普及组第3题 采药 时间限制: 1 Sec  内存限制: 128 MB提交: 50  解决: 23[提交][状态][讨论版][命题人:外部导入] 题目描述 辰辰是个天资聪颖的孩子,他的 ...

  6. NOIP2008普及组第3题 传球游戏

    NOIP2008普及组第3题 传球游戏 时间限制: 1 Sec  内存限制: 128 MB提交: 29  解决: 16[提交][状态][讨论版][命题人:外部导入] 题目描述 上体育课的时候,小蛮的老 ...

  7. NOIP2004普及组第3题 FBI树

    /* 1106: NOIP2004普及组第3题 FBI树 时间限制: 1 Sec 内存限制: 128 MB 提交: 10 解决: 9 [提交] [状态] [讨论版] [命题人:外部导入] 题目描述 我 ...

  8. 普及C组第四题(8.9)

    2298. [noip普及组2T4]异或 (File IO): input:gcdxor.in output:gcdxor.out 题目描述 SarvaTathagata是个神仙,一天他在研究数论时, ...

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

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

随机推荐

  1. 关于masonry

    简单的就不说了,网上很多教程 设置优先级 [label setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis ...

  2. 打开myeclipse2014的包资源管理器

    网上查到的方法不太适用于myeclipse2014,我就自己试了一下下 结果是:windows->show view->general->project package 结果: 希望 ...

  3. suricata抓包方式之一AF_PACKET

    suricata抓包方式之一AF_PACKET 噜拯渡 睦坚削 曜纡宄 式犒藿氆 咬焚桤φ 要蒯钮 喃俚夼 币噎嶂颐 话千叶舞就后悔了怎么想都容易让人引 虻谮м 及葚雏钏 看着表面平静实际 ...

  4. Learning from the CakePHP source code - Part II

    原文:http://debuggable.com/posts/learning-from-the-cakephp-source-code-part-ii:480f4dd6-57fc-4715-8709 ...

  5. input 和raw_input

    ---恢复内容开始--- 因为看python2 和 3 混了,所以两者里面的东西有点乱input 和raw_input 今天终于搞明白了,在这里记录一下: 1.python 2 中raw_input ...

  6. jQuery(4)—— jQuery中的事件

    jQuery中的事件 [加载DOM] 在常规的JavaScript代码中,通常使用window.onload方法,在jQuery中,使用的是$(document).ready()方法.极大地提高了we ...

  7. Collector

    安装 参考安装文章   创建项目project 转到你创建的目录,运行命令 django-admin.py startproject collector 生成下列文件 collector/ __ini ...

  8. [转]cmd-bat批处理命令延时方法

    批处理延时启动的几个方法 方法一:ping 缺点:时间精度为1秒,不够精确 @echo off @ping 127.0.0.1 -n 6 >nul start gdh.txt 方法二:vbs s ...

  9. msyql sql语句

    参考: http://www.cnblogs.com/aspnethot/articles/1397130.html 修改表字段ALTER TABLE table_name CHANGE old_fi ...

  10. python网络编程之网络主机信息

    功能: 获取设备名称 方法: gethostname() 参数: 返回值:hostname(string) 功能: 获取设备ipv4地址 方法: gethostbyname() 参数: hostnam ...