NOIP2015 T4 推销员 贪心+堆优化
前几天在学堆,这个数据结构貌似挺简单的,但是我看了很久啊QAQ...
今天算是搞懂了吧...于是想到了这道题...(当初悄悄咪咪看题解记得一点)
放洛谷的题...
题意的话,大概就是有n个房子在一条直线上,每个房子有一个离起点的距离,还有一个价值。
然后n个询问,第 i 个表示选 i 个房子能得到的最大总价值。总价值指 最远距离*2+每一个推销房子的价值。
有一个前提,不多走路,也就是说这个最远距离必须是某个要推销的房子。
思路:我萌可以考虑一下贪心,对于第i个询问,是否可以从第 i-1 个询问的基础上来得到捏?
当然可以辣!(然而不会证明QAQ)
辣我萌就假装证明完了的样子,
所以第 i 个询问的答案只需要在第 i-1 的询问答案加上一个最优值,也就是选择一个地方进行推销。
我萌可以这样考虑,假设在第 i-1 个询问的答案为lastans,这个最优解当前的最远房子为max
然后分类讨论,对于一个房子 x ,如果在max左边(x<max),辣么这个房子对答案的影响为 a[x]。
如果在max右边(x>max),辣么这个房子对答案的影响为 s[x]*2+a[x]-s[max]*2。
所以我萌每次都在去枚举一重 x 找到影响最大的,然后输出 lastans+影响值。
并更新 lastans和max。
但对于100%的数据O(n^2)是要tle的,辣就想想优化。
找最大值!会想到很多数据结构都可以维护。这里我选了刚学的堆。当然有很大原因是因为之前看的题解是堆
如何去优化捏。这样考虑,对于 x<max 的情况建一个堆heap0,对于 x>max 的情况建一个堆heap1。
刚开始的时候把heap1这个堆初始为全部 s[i]*2+a[i] (1≤i≤n) heap0这个堆初始为空。
然后每次查询前,如果heap1的堆首是<=max的就都删掉。
比较一下heap1的堆首和heap0的堆首,更新。
如果heap1的堆首更优,就把所有 没在heap0堆的且小于新max的都加入到heap0堆里。
这题我觉得题灰常的好啊QAQ,毕竟花了好久才搞出来...不过必须吐槽官方数据太弱了...
type
node=record
num:longint;
id:longint;
end;
var n,i,j:longint;
num,lastans:longint;
max,x:longint;
s,a:array[..]of longint;
v:array[..]of boolean;
heap:array[..,..]of node; tot,tot0:longint;
procedure swap(var a,b:node);
var t:node;
begin
t:=a;a:=b;b:=t;
end;
procedure down(x,b:longint);
begin
while x*<=n do
begin
if heap[x*,b].num>heap[x*+,b].num then
begin
if heap[x,b].num<heap[x*,b].num then
begin
swap(heap[x,b],heap[x*,b]);
x:=x*;
end else break;
end else
begin
if heap[x,b].num<heap[x*+,b].num then
begin
swap(heap[x,b],heap[x*+,b]);
x:=x*+;
end else break;
end;
end;
end;
procedure up(x:longint);
begin
while x> do
begin
if heap[x div ,].num<heap[x,].num then
begin
swap(heap[x div ,],heap[x,]);
x:=x div ;
end else break;
end;
end;
procedure build(n:longint);
var i:longint;
begin
for i:=n div downto do
down(i,);
end;
begin
read(n);
for i:= to n do
read(s[i]);
for i:= to n do
read(a[i]);
for i:= to n do
begin
heap[i,].num:=s[i]*+a[i];
heap[i,].id:=i;
end;
tot:=n;
build(n);
for i:= to n do
begin
while (heap[,].id<=max)and(tot>) do
begin
heap[,].num:=;
swap(heap[,],heap[tot,]);
down(,);
dec(tot);
end;
if (heap[,].num+lastans>num) then
begin
num:=lastans+heap[,].num;
x:=heap[,].id;
end;
if heap[,].num+lastans-s[max]*>num then
begin
num:=heap[,].num+lastans-s[max]*;
x:=heap[,].id;
for j:= to x- do
if not v[j] then
begin
v[j]:=true;
inc(tot0);
heap[tot0,].num:=a[j];
heap[tot0,].id:=j;
up(tot0);
end;
max:=x;
end;
writeln(num);
lastans:=num;
if x<max then
begin
heap[,].num:=;
swap(heap[,],heap[tot0,]);
down(,);
dec(tot0);
end;
end;
end. //堆的维护都是自己写的,很丑啊QAQ
NOIP2015 T4
NOIP2015 T4 推销员 贪心+堆优化的更多相关文章
- bzoj1555 KD之死 贪心+堆优化
1555: KD之死 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 124 Solved: 54[Submit][Status][Discuss] D ...
- [2016湖南长沙培训Day4][前鬼后鬼的守护 chen] (动态开点线段树+中位数 or 动规 or 贪心+堆优化)
题目大意 给定一个长度为n的正整数序列,令修改一个数的代价为修改前后两个数的绝对值之差,求用最小代价将序列转换为不减序列. 其中,n满足小于500000,序列中的正整数小于10^9 题解(引自mzx神 ...
- 【BZOJ1029】[JSOI2007] 建筑抢修(堆优化贪心)
点此看题面 大致题意: 有N个受到严重损伤的建筑,对于每个建筑,修好它需要\(T1\)秒,且必须在\(T2\)秒之前修完(\(T1\)与\(T2\)不是固定值),问你最多能修好几个建筑. 题解 一看到 ...
- Codeforces Round #303 (Div. 2) E. Paths and Trees Dijkstra堆优化+贪心(!!!)
E. Paths and Trees time limit per test 3 seconds memory limit per test 256 megabytes input standard ...
- 学习笔记·堆优化$\mathscr{dijkstra}$
嘤嘤嘤今天被迫学了这个算法--其实对于学习图论来说我内心是拒绝的\(\mathscr{qnq}\) 由于发现关于这个\(\mathscr{SPFA}\)的时间复杂度\(O(kE)\)中的\(k \ap ...
- Dijkstra+优先队列 堆优化
关于堆优化 传统\(Dijkstra\),在选取中转站时,是遍历取当前最小距离节点,但是我们其实可以利用小根堆(STL的priority_queue)优化这个过程,从而大大降低复杂(\(O(V2+E) ...
- 【bzoj5197】[CERC2017]Gambling Guide 期望dp+堆优化Dijkstra
题目描述 给定一张n个点,m条双向边的无向图. 你要从1号点走到n号点.当你位于x点时,你需要花1元钱,等概率随机地买到与x相邻的一个点的票,只有通过票才能走到其它点. 每当完成一次交易时,你可以选择 ...
- 【bzoj4070】[Apio2015]雅加达的摩天楼 set+堆优化Dijkstra
题目描述 印尼首都雅加达市有 N 座摩天楼,它们排列成一条直线,我们从左到右依次将它们编号为 0 到 N−1.除了这 N 座摩天楼外,雅加达市没有其他摩天楼. 有 M 只叫做 “doge” 的神秘生物 ...
- 【bzoj5047】空间传送装置 堆优化Dijkstra
题目描述 n个点e条边的有向图,每条边是m种类型之一.第i种类型在第x时刻通过所花费的时间为$(a_i*x+b_i)\mod c_i+d_i$.可以在某个点停留.问:在s时刻从1号点出发,到达每个点所 ...
随机推荐
- 观 浅谈HTTP中Get与Post的区别
看完解决了一些模糊不清的.错误的理解.
- git学习——<三>git操作
一.创建仓库 创建一个目录 mkdir repository cd到该目录下,初始化该版本库 git init 至此,版本库创建成功,可以在该文件夹下看到.git文件夹,ls -ah可以看到该文件夹. ...
- django中使用redis
第一种 安装redis模块 1.1在app中定义一个redis的连接池的py文件 import redis POOL=redis.ConnectionPool(host='127.0.0.1',por ...
- Docker中安装配置Oracle数据库
本文使用的OS是Ubuntu([16.04.1_server][1])[注:Ubuntu是安装在vmware虚拟机上的]. 其他的Oracle连接工具:[sqldeveloper-4.1.5.21.7 ...
- js-jquery-002-条形码-一维码
一.使用 官方地址:http://barcode-coder.com/en/barcode-jquery-plugin-201.html 1.js引用 <script type="te ...
- Spring MVC学习(五)---ModelAndView没有明显申明name
看图不解释: 对于这种写法: new ModelAndView().addObject(XXX)
- 深入理解Flink核心技术(转载)
作者:李呈祥 Flink项目是大数据处理领域最近冉冉升起的一颗新星,其不同于其他大数据项目的诸多特性吸引了越来越多的人关注Flink项目.本文将深入分析Flink一些关键的技术与特性,希望能够帮助读者 ...
- mysql 提示符显示用户,数据库等信息
命令: mysql -uroot -p --prompt="\\u@\\h:\\d \\r:\\m:\\s>" 效果: root@localhost:(mysql) 02:2 ...
- C++学习笔记-操作符重载
操作符重载(operator overloading)是一种形式的C++多态,C++将操作符重载扩展到用户自定义的类型,如允许使用+将两个自定义的对象相加,编译器将根据操作数的数目和类型决定使用那种加 ...
- SQL Server扩展属性的增、删、改、查
使用 sql 语句创建表时,可以使用系统存储过程 sp_addextendedproperty 给字段添加描述说明. sp_addextendedproperty 语法: sp_addextended ...