AcWing 数据备份

AcWing 数据备份

Description

  • 你在一家IT公司为大型写字楼或办公楼的计算机数据做备份。

    然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽享计算机游戏的乐趣。

    已知办公楼都位于同一条街上,你决定给这些办公楼配对(两个一组)。

    每一对办公楼可以通过在这两个建筑物之间铺设网络电缆使得它们可以互相备份。

    然而,网络电缆的费用很高。

    当地电信公司仅能为你提供 K 条网络电缆,这意味着你仅能为 K 对办公楼(总计2K个办公楼)安排备份。

    任意一个办公楼都属于唯一的配对组(换句话说,这 2K 个办公楼一定是相异的)。

    此外,电信公司需按网络电缆的长度(公里数)收费。

    因而,你需要选择这 K 对办公楼使得电缆的总长度尽可能短。

    换句话说,你需要选择这 K 对办公楼,使得每一对办公楼之间的距离之和(总距离)尽可能小。

    下面给出一个示例,假定你有 5 个客户,其办公楼都在一条街上,如下图所示。

    这 5 个办公楼分别位于距离大街起点 1km, 3km, 4km, 6km 和 12km 处。

    电信公司仅为你提供 K=2 条电缆。

    上例中最好的配对方案是将第 1 个和第 2 个办公楼相连,第 3 个和第 4 个办公楼相连。

    这样可按要求使用 K=2 条电缆。

    第 1 条电缆的长度是 3km-1km=2km ,第 2 条电缆的长度是 6km-4km=2km。

    这种配对方案需要总长 4km 的网络电缆,满足距离之和最小的要求。

Input

  • 第一行输入整数n和k,其中 n 表示办公楼的数目,k 表示可利用的网络电缆的数目。

    接下来的n行每行仅包含一个整数s,表示每个办公楼到大街起点处的距离。

    这些整数将按照从小到大的顺序依次出现。

Output

  • 输出应由一个正整数组成,给出将2K个相异的办公楼连成k对所需的网络电缆的最小总长度。

Sample Input

5 2 
1
3
4
6
12

Sample Output

4

题解:

  • 二叉堆。

  • 妙题,妙不可言。

  • 同时,我一开始用指针写这题调了我2天还没调出来。(我吃柠檬呢我艹。然后就数组模拟指针就过了。

  • 首先能想到的是肯定要相邻办公楼匹配。所以第一步先求出每两个相邻办公室间的距离,记住d1, d2, d3, …, d(n - 1)。那么问题就转化为:从D中选K个数使其之和最小,且相邻两个数不能被同时被选。

  • 这题还是用问题缩放技巧。先想想K是最小数据规模的情况。当K = 1时,显然答案就是D中的min值。当K = 2时,显然答案有如下两种情况:

    1. 选择最小值di, 以及除了d(i - 1), d(i), d(i + 1)之外数中的min值
    2. 选择最小值di两侧的两个数d(i - 1)和d(i + 1)
    • 理由:这非常容易理解,我不知道如何解释。
  • 那么如果K = K呢?利用问题缩放技巧和数学归纳法,发现小规模规律是满足大规模数据的。于是我们设计出这么一种算法:先选择D中的min值,然后删除d(i - 1), d(i), d(i + 1),再插入d(i - 1) + d(i + 1) - d(i)到刚才的位置。然后求解“从新的D中选择K - 1个数”。

  • 这么设计的话,如果取了d(i - 1) + d(i + 1) - d(i)这个数的话,就是上述第2种情况。没取到就是第1种情况。这恰好实现了我们上述的2种情况。

  • “选择D中min值”这一步可以用堆实现。但我偷懒就是set代替堆了。

#include <iostream>
#include <cstdio>
#include <set>
#define N 100005
#define int long long
using namespace std;

struct Node
{
    int val, pos;
    friend bool operator < (Node x, Node y) {
        if(x.val == y.val) return x.pos < y.pos;
        else return x.val < y.val;
    }
};
int n, k, ans;
int d[N], pre[N], nex[N];
set<Node> st;

int read()
{
    int x = 0; char c = getchar();
    while(c < '0' || c > '9') c = getchar();
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
    return x;
}

signed main()
{
    cin >> n >> k;
    for(int i = 1; i <= n; i++) d[i] = read();
    for(int i = 1; i < n; i++) pre[i] = i - 1, nex[i] = i + 1;
    pre[n] = n - 1, nex[0] = 1;
    for(int i = 1; i < n; i++)
    {
        d[i] = d[i + 1] - d[i];
        st.insert((Node){d[i], i});
    }
    d[0] = d[n] = (int)1e9;
    for(int i = 1; i <= k; i++)
    {
        int pos = (*st.begin()).pos;
        ans += d[pos], st.erase(st.begin());
        st.erase((Node){d[pre[pos]], pre[pos]});
        st.erase((Node){d[nex[pos]], nex[pos]});
        d[pos] = d[pre[pos]] + d[nex[pos]] - d[pos];
        st.insert((Node){d[pos], pos});
        pre[pos] = pre[pre[pos]], nex[pos] = nex[nex[pos]];
        nex[pre[pos]] = pos, pre[nex[pos]] = pos;
    }
    cout << ans;
    return 0;
}

转载于:https://www.cnblogs.com/BigYellowDog/p/11361329.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
ACwing是一个在线的程序设计竞赛训练平台,提供了丰富的算法题目和解题思路。在ACwing上,数据结构是其中一个重要的学习内容。根据引用内容,我们可以得出以下观点。 首先,数据结构在解决问题时起到了至关重要的作用。STL(Standard Template Library,标准模板库)是一种常用的C++库,其中包含了各种数据结构和算法。然而,STL不一定能够满足所有的需求,有些问题可能需要使用数组来解决。因此,学习数组的方法对于实现各种数据结构是非常重要的。 其次,使用结构体和指针来创建数据结构节点时,每次创建一个新节点都需要执行new Node()操作,这个操作可能会比较慢。特别是在处理大量数据的情况下,频繁的new操作可能导致运行时间超时。因此,在设计数据结构时需要考虑到运行效率的问题。 最后,在比赛中,通常没有进行O2优化。在这种情况下,纯STL可能会比数组模拟的数据结构稍慢一些。这是因为STL包含了更多的细节和抽象,而数组模拟的数据结构更为直接和简单。然而,在实际应用中,选择使用哪种数据结构还是要根据具体问题的需求和性能要求来决定。 综上所述,ACwing数据结构包含了使用STL和数组等不同的方法来实现各种数据结构。根据具体问题的需求和性能要求,选择合适的数据结构方法是很重要的。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [【AcWing 算法基础课】 2、数据结构 笔记](https://blog.csdn.net/qq_40915831/article/details/124761243)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值