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

试题描述
阿明是一名推销员,他奉命到螺丝街推销他们公司的产品。螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户。螺丝街一共有 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. Grunt使用教程(限winows)

    前提:安装nodejs 一. 打开dos命令窗口,输入命令 "node -v",确认nodejs安装成功 二. 其次,安装grunt-cli (该插件是grunt命令行插件),执行 ...

  2. php笔记(六)PHP类与对象之对象接口

    接口的实现 <?php //interface 关键字用于定义一个接口 interface ICanEat{ //接口里面的方法不需要实现 public function eat($food); ...

  3. css中position中的几个属性

    static  是默认值.任意 position: static; 的元素不会被特殊的定位.一个 static 元素表示它不会被"positioned",一个 position 属 ...

  4. Openlayer 3 最简单的弹出框

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. bootstrap如何自定义5等分

    根据bootstrap源码改的1比5的栅格系统 /*5等分媒体查询样式begin*/ .col-xs-1-5,.col-sm-1-5,.col-md-1-5,.col-lg-1-5,.col-xs-4 ...

  6. Spring-MVC填坑之旅-返回json数据

    本文是自己开发中所遇到的问题,对一些及百度到的解决方案做一个记录. DispatcherServlet配置文件 <!-- 定义跳转的文件的前后缀 ,视图模式配置--> <bean i ...

  7. hadoop MapReduce - 从作业、任务(task)、管理员角度调优

    Hadoop为用户作业提供了多种可配置的参数,以允许用户根据作业特点调整这些参数值使作业运行效率达到最优. 一 应用程序编写规范 1.设置Combiner         对于一大批MapReduce ...

  8. 发布webService

    创建webservices项目 1>创建web项目>添加新建项>webService>确认 注:webservices项目相当于就是UI ******************* ...

  9. javaWEB总结(14):请求的转发和重定向

    通俗理解请求转发与重定向的流程 通俗的来讲:我们可以把请求转发和重定向当成是一种借钱的情景模式. (1)请求的转发:A向B借钱,B自己没有钱,但是向C借到了钱,并且把钱借给了A.A只向B请求了一次. ...

  10. day01(RESTful Web Service、SVN)

    今日大纲 搭建SSM环境 基于SSM环境实现用户管理系统 学习RESTful Web Service 学习SVN 统一开发环境 JDK1.7 32? 64? -- 64 Eclipse 使用4.4.1 ...