码迷,mamicode.com
首页 > 其他好文 > 详细

数据备份

时间:2020-03-21 10:10:09      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:i+1   lan   i++   div   ras   problem   设置   pair   erase   

# 题意
给定n个位置(距离原点),每个位置上有一个公司,k表示可以用的网线数量,每个网线将连接两个公司且每一个公司只能连接一个网线,求满足k对配对情况下,所有电缆长度的最小值。

# 题解
最小值两边的距离要么不选,要么同时选,因为选了最小值就不能选旁边的所以每次选择最小的,并把最小的两边的和减去最小的加入到集合之中,因为两者相加即除了最小值的两边,并且当前的当要在最小值外选扩展另一条边的时候d[i-1] + d[i+1] -d[i] 正好能表示两条边的时候会增加的值,将这个入堆,不断选最小值并执行当前的操作最后就是最优值,因为d[i-1]和d[i+1]有边界的问题所以设置边界为值域内的无穷大,保证永远不会作为选择被选

 1 #include <bits/stdc++.h>
 2 #define pli pair<long long ,int>
 3 using namespace std;
 4 const int N=1e5+10;
 5 long long d[N];
 6 int l[N],r[N];
 7 int n,k;
 8 void move_node(int i){
 9    r[l[i]]=r[i];
10    l[r[i]]=l[i];
11 }
12 int main(){
13    cin>>n>>k;
14    set<pli>s;
15    for(int i=1;i<=n;i++)
16       cin>>d[i];
17    for(int i=n;i>=1;i--)
18       d[i]-=d[i-1];
19 
20    d[1]=d[n+1]=INT_MAX;
21    for(int i=1;i<=n+1;i++){
22       l[i]=i-1;
23       r[i]=i+1;
24       s.insert({d[i],i});
25    }
26    long long ans=0;
27 
28    while(k--) {
29       auto t=s.begin();
30       long long a=t->first;
31       int p = t->second,left=l[p],right=r[p];
32       s.erase(t);
33       s.erase({d[left],left}),s.erase({d[right],right});
34       move_node(left),move_node(right);
35       ans+=a;
36       d[p]=d[left]+d[right]-d[p];
37       s.insert({d[p],p});
38    }
39    cout<<ans;
40 }

 

数据备份

标签:i+1   lan   i++   div   ras   problem   设置   pair   erase   

原文地址:https://www.cnblogs.com/hhyx/p/12536318.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!