题目链接:BZOJ - 1150

题目分析

可以看出,我们选的 k 条边一定是相邻两点之间的线段。我们可以将每条边看成一个点,那么我们就是要在 n-1 个点中选出互不相邻的 k 个,使它们的和最小。

我们使用一种神奇的贪心,开始的时候将所有的点权加入堆中,然后取 k 次,每次取权值最小的点,然后将这个点的点权加入答案中,我们取了这个点之后就不能取与它相邻的两个点了,所以我们要将这个点和相邻两点的权值都从堆中删除。但是我们最终的答案并不一定要取这个点,有可能我们会不取这个点,而是取与它相邻的两个点。所以我们在删除了这个点和与它相邻的两个点之后,要在堆里加入一个新的点:权值是与这个点相邻的两个点的权值和-这个点的权值,如果之后取到这个新的点就相当于撤销取这个点,而是取与它相邻的两个点,这样取到的点数还是加一的。

然后这样处理之后我们就认为这个新建的点取代了之前的3个点的位置,然后与这3个点两边的点相邻,需要用链表维护。

还有特殊的情况,对于两端的点,与它们相邻的点只有1个,我们要在第一个点之前和最后一个点之后分别加上一个权值为 INF 的点,这样进行处理之后新建的点的权值也一定非常大,之后就不会被取到。

代码

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <set> using namespace std; const int MaxN = 100000 + 5, INF = 999999999; int n, k, Ans;
int A[MaxN], d[MaxN], Next[MaxN], Prev[MaxN]; struct ES
{
int x, y;
ES() {}
ES(int a, int b) {x = a; y = b;} bool operator < (const ES &e) const
{
if (y == e.y) return x < e.x;
return y < e.y;
}
}; set<ES> S;
set<ES> :: iterator It; int main()
{
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; ++i)
{
scanf("%d", &d[i]);
A[i] = d[i] - d[i - 1];
}
for (int i = 2; i <= n; ++i)
{
Next[i] = i + 1;
Prev[i] = i - 1;
S.insert(ES(i, A[i]));
}
A[1] = A[n + 1] = INF;
int x;
for (int i = 1; i <= k; ++i)
{
It = S.begin();
x = (*It).x;
Ans += A[x];
S.erase(ES(x, A[x]));
S.erase(ES(Prev[x], A[Prev[x]]));
S.erase(ES(Next[x], A[Next[x]]));
A[x] = A[Prev[x]] + A[Next[x]] - A[x];
S.insert(ES(x, A[x]));
if (Prev[Prev[x]]) Next[Prev[Prev[x]]] = x;
if (Next[Next[x]]) Prev[Next[Next[x]]] = x;
Prev[x] = Prev[Prev[x]];
Next[x] = Next[Next[x]];
}
printf("%d\n", Ans);
return 0;
}

  

[BZOJ 1150] [CTSC2007] 数据备份Backup 【贪心 + 链表】的更多相关文章

  1. bzoj 1150: [CTSC2007]数据备份Backup【链表+堆】

    参考:http://blog.csdn.net/Regina8023/article/details/44158947 神奇的做法.题意相当于若干个数取不相邻的k个使最小.先把数组差分,len表示这段 ...

  2. 【链表】bzoj 1150: [CTSC2007]数据备份Backup

    1150: [CTSC2007]数据备份Backup Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1136  Solved: 458[Submit] ...

  3. bzoj 1150: [CTSC2007]数据备份Backup

    Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家 ...

  4. BZOJ 1150 [CTSC2007]数据备份Backup(贪心+优先队列)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1150 [题目大意] 给出n个数,请你挑出k对(每个数不可重复选取),使得他们差的绝对值 ...

  5. BZOJ 1150 CTSC2007 数据备份Backup 堆+馋

    标题效果:给定一个长度n−1n-1的序列,要求选出kk个不相邻的数使得和最小 费用流显然能跑.并且显然过不去- - 考虑用堆模拟费用流 一个错误的贪心是每次取最小.这样显然过不去例子 我们把[每次取最 ...

  6. 【BZOJ 1150】 1150: [CTSC2007]数据备份Backup (贪心+优先队列+双向链表)

    1150: [CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设 ...

  7. 1150: [CTSC2007]数据备份Backup

    1150: [CTSC2007]数据备份Backup https://lydsy.com/JudgeOnline/problem.php?id=1150 分析: 堆+贪心. 每次选最小的并一定是最优的 ...

  8. BZOJ1150 [CTSC2007] 数据备份Backup 贪心_堆_神题

    Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家 ...

  9. BZOJ1150 [CTSC2007]数据备份Backup 贪心 堆

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1150 题意概括 数轴上面有一堆数字. 取出两个数字的代价是他们的距离. 现在要取出k对数,(一个数 ...

随机推荐

  1. 为ubuntu只带的network-manager添加latp/ipsec VPN

    sudo apt-add-repository ppa:seriy-pr/network-manager-l2tp sudo apt-get update sudo apt-get install n ...

  2. fail-fast机制

    在JDK的Collection中我们时常会看到类似于这样的话: 例如,ArrayList: 注意,迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证.快速失 ...

  3. [转载]PHP 字符串替换中文

    $a = "Car 神"; $result = preg_replace('/([\x80-\xff]*)/i','',$a); var_dump($result); 参考链接:p ...

  4. JDK Tools - jps: JVM 进程状态工具

    jps(Java Virtual Machine Process Status Tool) 是 JDK 提供的一个显示当前所有 Java 进程实例的命令. 命令格式 jps [ options ] [ ...

  5. SQL Server调优系列进阶篇 - 深入剖析统计信息

    前言 经过前几篇的分析,其实大体已经初窥到SQL Server统计信息的重要性了,所以本篇就要祭出这个神器了. 该篇内容会很长,坐好板凳,瓜子零食之类... 不废话,进正题 技术准备 数据库版本为SQ ...

  6. Json 映射 的使用 及 JS 数组的使用

    Json 映射的使用: var nameMap = { 'A': 'A1', 'B': 'B1', 'B': 'B1' }; var selectedName='A'; if (nameMap[sel ...

  7. 准备Activiti的开发环境

    1.创建项目

  8. WPF设置窗口模式(Windowstyle=“None”)

    当WindowStyle="None"时,设置AllowsTransparency="True",则不会出现黑色Border,然后可以另外设置外边的Border ...

  9. Unity3D--学习太空射击游戏制作(一)

    近期买了本书在学习一些Unity3D的东西,在了解了Unity3D工具的基本面板后开始学习一个太空射击游戏的开发过程. 首先下载一个关于本游戏的资源文件,(百度云下载地址:http://pan.bai ...

  10. 关于静态库和动态库的理解(C++)

    库的存在,是软件模块化的基础. 库存在的意义: } 库是别人写好的现有的,成熟的,可以复用的代码,你可以使用但要记得遵守许可协议.      } 现实中每个程序都要依赖很多基础的底层库,不可能每个人的 ...