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

1150: [CTSC2007]数据备份Backup

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1136  Solved: 458
[Submit][Status][Discuss]

Description

 

Input

输入的第一行包含整数n和k,其中n(2 ≤ n ≤100 000)表示办公楼的数目,k(1≤ k≤ n/2)表示可利用的网络电缆的数目。接下来的n行每行仅包含一个整数(0≤ s ≤1000 000 000), 表示每个办公楼到大街起点处的距离。这些整数将按照从小到大的顺序依次出现。

Output

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

Sample Input

5 2
1
3
4
6
12

Sample Output

4

HINT

 

上面的样例输入给出了前面描述的示例情形 对于每一个测试点,如果写到输出文件中的答案正确,则得到该测试点100%的分数,否则得零分。30%的输入数据满足n≤20。60%的输入数据满足n≤10 000。


  一开始觉得要贪心什么的
  瞄了一眼题解
  貌似我再想一下能出来( 大雾
  然后感觉好困。。
  最后几乎是半抄完了
  易得每次只能选相邻点
  所有只有n-1条边可选
  每次链表选最小的
  然后选完后合并前一个和后一个
  具体来说就是堆维护最小值
  每次合并-->该边和上一条和下一条不可选,创建一个新的节点代替原来的三个,ans加上权值
  权值是左边+右边-中间(再选新节点=不选中间选两边)
  还有就是选队首队尾,则易得选队首的后一个和选队尾的前一个不可能优。
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<queue>
 6 
 7 #define maxn 1000001
 8 
 9 using namespace std;
10 
11 int a[maxn*2],n,k,pre[maxn*2],next[maxn*2],num=0;
12 
13 long long cha[maxn*2],ans=0;
14 
15 bool vis[maxn*2];
16 
17 struct node{
18     int x;
19     long long c;
20     bool operator <(const node &A)const{
21         if(A.c==c)return x>A.x;
22         return c>A.c;
23     }
24 };
25 
26 priority_queue<node>q;
27 
28 inline int in()
29 {
30     int x=0;char ch=getchar();
31     while(ch<'0'||ch>'9')ch=getchar();
32     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
33     return x;
34 }
35 
36 void Pre()
37 {
38     for(int i=1;i<n;i++)
39         cha[i]=a[i+1]-a[i],q.push((node){i,a[i+1]-a[i]}),pre[i]=i-1,next[i]=i+1;
40     num=n;
41     pre[n]=n-1;next[0]=1;
42 }
43 
44 void solve()
45 {
46     node Top;
47     for(int i=1;i<=k;i++)
48     {
49         Top=q.top();q.pop();
50         while(vis[Top.x])
51             Top=q.top(),q.pop();
52         if(pre[Top.x]==0)
53         {
54             pre[next[next[Top.x]]]=0;
55             ans+=Top.c;
56             vis[Top.x]=vis[next[Top.x]]=1;
57         }
58         else if(next[Top.x]==n)
59         {
60             next[pre[pre[Top.x]]]=n;
61             ans+=Top.c;
62             vis[Top.x]=vis[pre[Top.x]]=1;
63         }
64         else
65         {
66             ans+=Top.c;
67             node New;
68             New.x=++num;
69             New.c=cha[pre[Top.x]]+cha[next[Top.x]]-Top.c;
70             pre[New.x]=pre[pre[Top.x]],next[pre[New.x]]=New.x;
71             next[New.x]=next[next[Top.x]],pre[next[New.x]]=New.x;
72             vis[Top.x]=vis[next[Top.x]]=vis[pre[Top.x]]=1;
73             cha[num]=New.c;
74             q.push(New);
75         }
76     }
77 }
78 
79 int main()
80 {
81     n=in();k=in();
82     for(int i=1;i<=n;i++)a[i]=in();
83     Pre();solve();
84     printf("%lld",ans);
85     return 0;
86 }
View Code

 

posted @ 2015-10-10 19:36  puck_just_me  阅读(271)  评论(0编辑  收藏  举报