【链接】 我是链接,点我呀:)

【题意】

在这里输入题意

【题解】

选择的连接肯定是相邻的点对。

那么我们处理出来长度为n-1的数组a

其中a[i-1] = dis[i]-dis[i-1]

那么问题就转化成在a数组中取出不相邻的k个数字。

这k个数字的和要求最小。

那么我们把每个数字都加入到堆中去。

然后对于k个数字。

每次取出堆中的最小值x

累加答案

但是这样做可能不是正确的。

因为可能选择x-1,x+1这两个点比单独选择一个点来得更优一些。

(如果你发现选x不是最优的->不选x->那么肯定吧x-1和x+1都选了更好

因此我们得给程序一个"反悔"的机会。

怎么给呢?

我们可以把x-1,x+1两个点的权值和减去x的权值和->temp。

然后加入到堆中去。

然后把x-1,x+1这两个点删掉。

x这个点的权值设置为刚才提到的temp

(这里要注意的一个思想就是,把x-1,x,x+1看成是一个整体,

这样下次如果再选这个x,就表示x不选了而把x-1,x+1选上。

->累加答案

这时仍然把x看成是一个点。

把它左边(此时是x-2)右边(x+2)的点删掉.

然后把a[x-2]+a[x+2]-a[x]再加入到堆中

重复上述步骤就好了

(这个时候-a[x]其实就是把那个"整体"里面选的变成不选,不选的变成选的了

(只有这样,x-2和x+2才能够被选中

(而且x这个整体里面会发现选中的点的个数总是比没选中的点个数多恰好1,所以再把x-2,x+2加上,刚好只会增加一个选择的点

我们每一次取出答案。

其实都只会让选中的点的个数递增1

所以堆中的每个元素其实对应的是,再多选一个点的话。

增加的代价是多少。

而我们每次选的都是最小的代价。

因此贪心的策略是正确的。

【代码】

/**************************************************************
Problem: 1150
User: chengchunyang
Language: C++
Result: Accepted
Time:696 ms
Memory:5260 kb
****************************************************************/ #include <bits/stdc++.h>
#define ll long long using namespace std; const int N = 1e5;
const int INF = 1e9+10; int n,k;
int dis[N+10],a[N+10],L[N+10],R[N+10];
priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > >pq;
bool vis[N+10]; int main()
{
scanf("%d%d",&n,&k);
for (int i = 1;i <= n;i++) scanf("%d",&dis[i]);
for (int i = 2;i <= n;i++) a[i-1] = dis[i]-dis[i-1];
n--;
a[0] = INF,a[n+1] = INF;
for (int i = 0;i <= n+1;i++) L[i] = i-1,R[i] = i+1;
for (int i = 1;i <= n;i++) pq.push(make_pair(a[i],i));
ll ans = 0;
for (int i = 1;i <= k;i++){
pair<ll,int> x;
do{
x = pq.top();pq.pop();
}while (vis[x.second]);
int id = x.second;
ans+=a[id];
a[id] = a[L[id]]+a[R[id]]-a[id];
pq.push(make_pair(a[id],id));
vis[L[id]] = vis[R[id]] = 1;
R[L[L[id]]] = id;
L[R[R[id]]] = id;
L[id] = L[L[id]];
R[id] = R[R[id]];
}
printf("%lld\n",ans);
return 0;
}

最新文章

  1. 异步HTTPHandler的实现
  2. 如何将页面的&lt;br/&gt;在Excel中正确换行
  3. callee的用法
  4. Node.js高级编程读书笔记 - 5 数据库 - Never
  5. Metaweblog在Android上使用
  6. c#基础语言编程-集合
  7. iOS开发之property属性介绍
  8. Android开发之模板模式初探
  9. MVC3.0+knockout.js+Ajax 实现简单的增删改查
  10. win2008阿里一键环境包mysql老是1067报错
  11. HDU 4585 Shaolin (set的应用)
  12. 拓扑排序&lt;反向拓扑+有向环的判断&gt;
  13. visual studio 2015 warning MSB3246
  14. Mac OS X下让ruby支持tcl/tk
  15. shiro-core包引用的版本问题
  16. Python 安装第三方库中常见问题总结
  17. CAN协议,系统结构和帧结构
  18. linux tomcat jvm调优
  19. mysql查询操作之单表查询、多表查询、子查询
  20. spring中的scope详解

热门文章

  1. django patch
  2. CSS布局总结(三)
  3. C# Windows Api的一些方法 封装 以及 常用参数
  4. 页面下载文件方法,post与get
  5. Python数学实现二元一次方程
  6. 如何使用JAVA请求HTTPS
  7. Android开发之AlarmManager具体解释
  8. CSS3弹性布局内容对齐(justify-content)属性使用具体解释
  9. win10+ubuntu双系统卸载ubuntu
  10. chrome的F12的inspect使用