kick start 2019 round D T3题解
---恢复内容开始---
题目大意:共有N个房子,每个房子都有各自的坐标X[i],占据每个房子需要一定花费C[i]。现在需要选择K个房子作为仓库,1个房子作为商店(与题目不同,概念一样),由于仓库到房子之间存在距离 | Xi-Xj | ,所以想要使“占据K+1个房子以及每个仓库到商店的距离和”最小化,并输出该最小值。
数据范围:K<N<=1e5,C[i],X[i]<=1e9。
解题思路:比赛期间使用的是N*N*log(N)的时间复杂度,总体思路是先选定商店位置,再将其他房子按照“花费+距离”进行快排,选出前K优的房子作为仓库。理想的时间复杂度是N*log(K)的,在看过题解后着实佩服google的题……曾经有人分我说过google出的题要是你没做出来,你也是心服口服的,现在我真的意识到了。
改解法依旧将问题剖解,首先是一个老生常谈的问题:如果已经选好了K+1个房子,那么商店放在哪合适?这是以往的基础题了,最后的结论是房子位置的中位数处。有了这样的概念后,在枚举商店时,就可以确认商店左右(关于X的左右)两边各有K/2间仓库(可能出现奇偶问题,大家可以自己想想)。于是来到下一个子问题:如何获得一个商店左侧C[i]-X[i]最小的K/2个值的和呢(这句话大家也可以想想),又如何获得一个商店右侧C[i]+X[i]最小的K-K/2个值的和呢?
这两个问题是强关联的(我最开始没发现。。真是傻),可以利用最大堆解决,以左侧为例,先将以X排序好的房子#1~#K/2的C[i]-X[i]值加入最大堆,并记录当前最值的最大堆所有元素和。当对#K/2+1~#N的房子依次进行分析时,首先看当前房间的C[i]-X[i]值是否小于最大堆的top值,若小于,则更新最大堆(弹出top,压入c[i]-x[i])与元素和。
维护好suml[]以及sumr[]两数组后,就可以枚举商店位置,计算以此处为商店的租界最小值,再将每个商店的租界最小值取最小值,即可得到答案。
语义不清。。有空再回顾一下重写吧。真是好题。
最终代码:
#include <stdio.h>
#include <queue>
#include <algorithm>
using namespace std; priority_queue<long long> qq;
struct ooo{
int xx,cc;
}hou[];
bool cmp(ooo a,ooo b){
return a.xx<b.xx;
}
int x[],c[];
long long suml[],sumr[];
int mainn()
{
int k,n;scanf("%d%d",&k,&n);
for (int i=;i<=n;i++) scanf("%d",&hou[i].xx);
for (int i=;i<=n;i++) scanf("%d",&hou[i].cc);
sort(hou+,hou+n+,cmp);
for (int i=;i<=n;i++)
{
x[i]=hou[i].xx;c[i]=hou[i].cc;
}
while (!qq.empty()) qq.pop();
suml[]=;
for (int i=;i<=n;i++)
{
if (k==)
{
suml[i]=;
continue;
}
if (i<=k/)
{
suml[i]=suml[i-]+c[i]-x[i];
qq.push(c[i]-x[i]);
continue;
}
if( c[i]-x[i] < qq.top() ){
suml[i]=suml[i-]-qq.top();
qq.pop();
qq.push(c[i]-x[i]);
suml[i]+=(c[i]-x[i]);
}
else
suml[i]=suml[i-];
}
while (!qq.empty()) qq.pop();
sumr[n+]=;
for (int i=n;i>;i--)
{
if ( qq.size()<k-k/ )
{
sumr[i]=sumr[i+]+c[i]+x[i];
qq.push(c[i]+x[i]);
continue;
}
if (c[i]+x[i]<qq.top() ){
sumr[i]=sumr[i+]-qq.top();
qq.pop();
qq.push(c[i]+x[i]);
sumr[i]+=(c[i]+x[i]);
}
else
sumr[i]=sumr[i+];
}
long long ans=-;
for (int i=k/+;i+k-k/<=n;i++)
{
long long tmp=c[i]+suml[i-]+sumr[i+];
if (k%) tmp-=x[i];
if (ans==- || ans>tmp)
ans=tmp;
}
printf(" %lld\n",ans);
//for (int i=1;i<=n;i++)
// printf("%lld %lld\n",suml[i],sumr[i]); } int main()
{
int T;scanf("%d",&T);
for (int i=;i<=T;i++)
{
printf("Case #%d:",i);
mainn();
}
}
题目链接:
https://codingcompetitions.withgoogle.com/kickstart/round/0000000000051061/0000000000161476
kick start 2019 round D T3题解的更多相关文章
- kick start 2019 round D T2题解
题目大意:由N个房子围成一个环,G个人分别顺时针/逆时针在房子上走,一共走M分钟,每分钟结束,每个人顺/逆时针走到相邻的房子.对于每个房子都会记录最后时刻到达的人(可能是一群人).最终输出每个人会被几 ...
- [多校联考2019(Round 5 T3)]青青草原的表彰大会(dp+组合数学)
[多校联考2019(Round 5)]青青草原的表彰大会(dp+组合数学) 题面 青青草原上有n 只羊,他们聚集在包包大人的家里,举办一年一度的表彰大会,在这次的表彰大会中,包包大人让羊们按自己的贡献 ...
- Kick Start 2019 Round A Contention
$\DeclareMathOperator*{\argmax}{arg\,max}$ 题目链接 题目大意 一排 $N$ 个座位,从左到右编号 $1$ 到 $N$ . 有 $Q$ 个预定座位的请求,第 ...
- Kick Start 2019 Round H. Elevanagram
设共有 $N = \sum_{i=1}^{9} A_i$ 个数字.先把 $N$ 个数字任意分成两组 $A$ 和 $B$,$A$ 中有 $N_A = \floor{N/2}$ 个数字,$B$ 中有 $N ...
- 【DP 好题】Kick Start 2019 Round C Catch Some
题目链接 题目大意 在一条数轴上住着 $N$ 条狗和一个动物研究者 Bundle.Bundle 的坐标是 0,狗的坐标都是正整数,可能有多条狗住在同一个位置.每条狗都有一个颜色.Bundle 需要观测 ...
- Kick Start 2019 Round A Parcels
题目大意 $R \times C$ 的网格,格子间的距离取曼哈顿距离.有些格子是邮局.现在可以把至多一个不是邮局的格子变成邮局,问每个格子到最近的邮局的曼哈顿距离的最大值最小是多少. 数据范围 $ 1 ...
- Kick Start 2019 Round B Energy Stones
对我很有启发的一道题. 这道题的解法中最有思维难度的 observation 是 For simplicity, we will assume that we never eat a stone wi ...
- Kick Start 2019 Round F Teach Me
题目链接 题目大意 有 $N$ 个人,$S$ 项技能,这些技能用 $1, 2, 3, \dots, S$ 表示 .第 $i$ 个人会 $c_i$ 项技能($ 1 \le c_i \le 5 $).对于 ...
- Kick Start 2019 Round D
X or What? 符号约定: $\xor$ 表示异或. popcount($x$) 表示非负整数 $x$ 的二进制表示里数字 1 出现的次数.例如,$13 = 1101_2$,则 popcount ...
随机推荐
- PID算法 旋转倒立摆与平衡车的区别。此贴后边会更新。
我做PID算法的背景和经历:本人之前电子信息科学与技术专业,对控制方向颇感兴趣,刚上大学时听到实验室老师说PID算法,那年在暑假集训准备全国电子设计竞赛,我正在练习做一个以前专科的题目,帆板角度控制系 ...
- Git应用之eclipse解决冲突代码
最近上班公司框架换成了微服务下面是eclipse 对代码进行管理 1.冲突代码 如果两个人在一个项目上同一文件上更改代码就会出现冲突现象 先用NewFile.jsp 文件做演示 打开eclipse从 ...
- hdu 6397 Character Encoding (生成函数)
Problem Description In computer science, a character is a letter, a digit, a punctuation mark or som ...
- 疯子的算法总结(二) STL Ⅰ 算法 ( algorithm )
写在前面: 为了能够使后续的代码具有高效简洁的特点,在这里讲一下STL,就不用自己写堆,写队列,但是做为ACMer不用学的很全面,我认为够用就好,我只写我用的比较多的. 什么是STL(STl内容): ...
- 【Java例题】4.1 级数求和1
1. 计算级数之和: y=1-1/2+1/4-1/8+...+ (-1)^(n-1)/2^(n-1). 这里的"^"表示乘方. package chapter4; import j ...
- dns自动配置shell脚本
代码: #!/bin/bash #获取url echo "url:" read url #获取ip echo "ip:" read ip #向/etc/name ...
- hadoop hdfs 分布式存储
1.克隆前的工作 1.配置好网络nat 需要设置静态ip并能通过主机上网 ssh 和 rsync 是必须下载的 2.yum install vim wget rsync ssh 并配 ...
- tomcat和weblogic发布时,jar包内资源文件的读取路径问题
问题场景: 本地使用的是tomcat作为发布容器,应用启动后一切正常: 发布测试环境服务器使用weblogic作为发布容器,发布后File类读取文件无法找到文件(路径错误). 问题原因: tomcat ...
- c语言ld returned 1 exit status😂
在复习c语言过程中遇到, 问题:reverseLinkedList.exe: Permission denied collect2.exe: error: ld returned 1 exit sta ...
- docker/kubernetes国内源/镜像源解决方式
最近在使用kubeadm时,被各种连接不上搞到崩溃.费了很多力气,基本都解决了.这里统一整理了国内的一些镜像源,apt源,kubeadm源等,以便查阅. 国内镜像源 Azure China提供了目前用 ...