---恢复内容开始---

  题目大意:共有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题解的更多相关文章

  1. kick start 2019 round D T2题解

    题目大意:由N个房子围成一个环,G个人分别顺时针/逆时针在房子上走,一共走M分钟,每分钟结束,每个人顺/逆时针走到相邻的房子.对于每个房子都会记录最后时刻到达的人(可能是一群人).最终输出每个人会被几 ...

  2. [多校联考2019(Round 5 T3)]青青草原的表彰大会(dp+组合数学)

    [多校联考2019(Round 5)]青青草原的表彰大会(dp+组合数学) 题面 青青草原上有n 只羊,他们聚集在包包大人的家里,举办一年一度的表彰大会,在这次的表彰大会中,包包大人让羊们按自己的贡献 ...

  3. Kick Start 2019 Round A Contention

    $\DeclareMathOperator*{\argmax}{arg\,max}$ 题目链接 题目大意 一排 $N$ 个座位,从左到右编号 $1$ 到 $N$ . 有 $Q$ 个预定座位的请求,第 ...

  4. Kick Start 2019 Round H. Elevanagram

    设共有 $N = \sum_{i=1}^{9} A_i$ 个数字.先把 $N$ 个数字任意分成两组 $A$ 和 $B$,$A$ 中有 $N_A = \floor{N/2}$ 个数字,$B$ 中有 $N ...

  5. 【DP 好题】Kick Start 2019 Round C Catch Some

    题目链接 题目大意 在一条数轴上住着 $N$ 条狗和一个动物研究者 Bundle.Bundle 的坐标是 0,狗的坐标都是正整数,可能有多条狗住在同一个位置.每条狗都有一个颜色.Bundle 需要观测 ...

  6. Kick Start 2019 Round A Parcels

    题目大意 $R \times C$ 的网格,格子间的距离取曼哈顿距离.有些格子是邮局.现在可以把至多一个不是邮局的格子变成邮局,问每个格子到最近的邮局的曼哈顿距离的最大值最小是多少. 数据范围 $ 1 ...

  7. Kick Start 2019 Round B Energy Stones

    对我很有启发的一道题. 这道题的解法中最有思维难度的 observation 是 For simplicity, we will assume that we never eat a stone wi ...

  8. Kick Start 2019 Round F Teach Me

    题目链接 题目大意 有 $N$ 个人,$S$ 项技能,这些技能用 $1, 2, 3, \dots, S$ 表示 .第 $i$ 个人会 $c_i$ 项技能($ 1 \le c_i \le 5 $).对于 ...

  9. Kick Start 2019 Round D

    X or What? 符号约定: $\xor$ 表示异或. popcount($x$) 表示非负整数 $x$ 的二进制表示里数字 1 出现的次数.例如,$13 = 1101_2$,则 popcount ...

随机推荐

  1. .NET Core CSharp 中级篇 2-2 List,ArrayList和Dictionary

    .NET Core CSharp 中级篇 2-2 本节内容为List,ArrayList,和Dictionary 简介 在此前的文章中我们学习了数组的使用,但是数组有一个很大的问题就是存储空间不足,我 ...

  2. javaweb入门-----jsp概念

    jsp是什么? JSP:Java Server Pages java服务器端页面 *可以理解为 一个特殊的页面,其中既可以直接定义html标签,又可以定义java代码 *用于简化书写 <% %& ...

  3. Usaco Training [1.3] wormhole

    传送门 解题要素:代码能力 解题步骤:理解题意 - >搜索枚举所有可能的配对情况 - >判断冲突并求解 - >调试 一. 理解题意 这里讲几个不容易理解的点: 1. +x方向 即向右 ...

  4. 使用抽象工厂反射获取不到Dal层对象,未能加载文件或程序集......

    Put aside the fog and see the essence 解决问题之前,要明白问题为什么会出现 我相信能点开这篇帖子的人,都是具有探索精神的人,因为,只有心存疑问才会搜索 如果只想单 ...

  5. 控制台基于Quartz.Net组件实现定时任务调度(一)

    前言: 你曾经需要应用执行一个任务吗?比如现在有一个需求,需要每天在零点定时执行一些操作,那应该怎样操作呢? 这个时候,如果你和你的团队是用.NET编程的话,可以考虑使用Quartz.NET调度器.允 ...

  6. Postgresql部署及简单操作

    PostgreSQL是一个功能强大的开源对象关系数据库管理系统(ORDBMS),在开源数据库使用上与MySQL各领风骚.但也有不少人质疑postgresql的未来,正所谓,赞扬或批判一种数据库都必须先 ...

  7. java虚拟机学习笔记(六)---垃圾收集算法

    主要讨论集中垃圾收集算法的思想及发展过程. 1.标记-清除法 最基础的收集算法是标记-清除法,算法分为标记和清除两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象,其标记过程 ...

  8. 简洁实用Socket框架DotNettySocket

    目录 简介 产生背景 使用方式 TcpSocket WebSocket UdpSocket 结尾 简介 DotNettySocket是一个.NET跨平台Socket框架(支持.NET4.5+及.NET ...

  9. 单机版ZooKeeper的安装教程

    之前一直没有时间去整理,现在抽出几分钟时间整理以下,有问题的在评论区留言即可. 前期准备JDK环境(ZK需要jdk进行编译,本文以jdk1.8.0_211为例).Linux系统(本文以Centos7为 ...

  10. 『开发技术』GPU训练加速原理(附KerasGPU训练技巧)

    0.深入理解GPU训练加速原理 我们都知道用GPU可以加速神经神经网络训练(相较于CPU),具体的速度对比可以参看我之前写的速度对比博文: [深度应用]·主流深度学习硬件速度对比(CPU,GPU,TP ...