洛谷P2242 公路维修问题

题目链接:https://www.luogu.com.cn/problem/P2242

问题描述

由于长期没有得到维修,A国的高速公路上出现了N个坑。为了尽快填补好这N个坑,A国决定对M处地段采取交通管制。为了求解方便,假设A国的高速公路只有一条,而且是笔直的。现在给出N个坑的位置,请你计算,最少要对多远的路段实施交通管制?

输入格式

输入数据共两行,第一行为两个正整数N、M (2<=N<=15000,M<=N)。第二行给出了N个坑的坐标(坐标值均在长整范围内,按从小到大的顺序给出,且不会有两个点坐标相同)。

输出格式

仅一行,为最小长度和。

输入输出样例

输入
   18 4
3 4 6 8 14 15 16 17 21 25 26 27 30 31 40 41 42 43
输出 
25

说明/提示

[样例说明]

交通管制的地段分别为:3-8,14-21,25-31,40-43。


 

解题思路:

  1.  排序+贪心
  2. 假设每一个坑都被管制了,但是由于管制的路段数量有限,所以就要减去尽可能大的没有坑路段,然后得出的就是答案了。

 贪心问题需要证明:

题目要求实施交通管制的路段总长度最短,我们就必须使管制的路段中被浪费的长度尽量小。因为只有坑所在的点才需要被维护,这里“被浪费的长度”,其实就是坑与坑之间的距离 ,即没有被管制的路段。

显然可以得出结论: 所有被管制路段的的开头和结尾一定都在坑上, 才能使浪费达到最小。所以我们需要考虑的其实是从第一个坑到第n个坑的范围,道路的头尾两端都可以省略。

那么问题就来了,在怎么在第一个坑和最后一个坑之间管制m个路段,使总浪费最小呢?

我们可以注意到,根据刚才得出的结论,在这m条路段中,第一条的开头一定是第一个坑,而第m条路段的结尾一定是第n个坑。每两个管制路段之间会有一个没有被管制的路段,所以,在第一个坑和第n个坑之间,

一共会有m-1个没有被管制的路段,即会有m-1“坑与坑之间的距离”会被浪费。

为了使浪费最短,我们就可以用sort对每两个坑之间的距离进行排序,然后用第一个坑到第n个坑之间的距离依次减去前m1个最 长的没有坑的路段,就可以求出答案了。

 

参考代码:

#include<iostream>
#include<bits/stdc++.h>           
int n,m;
int a[15005],b[15005],ans;
bool cmp(int x,int y){        //cmp函数用于让sort从大到小排列
	return x>y;
}

int main(){
   scanf("%d%d",&n,&m);
   for(int i=1;i<=n;i++)
       scanf("%d",&a[i]);
   ans = a[n] - a[1] + 1;
   for(int i=1;i<n;i++)       //计算出每一个坑的距离
       b[i] = a[i+1] - a[i];
   std::sort(b+1,b+n,cmp);    //从大到小排序
   for(int i=1;i<m;i++){      //从中间舍去m-1段不需要的最长的路段 
       ans = ans - b[i] + 1;
   }
   printf("%d\n",ans);
	
   return 0;                  
}

  

posted @ 2022-03-27 11:58  LuoJMeng  阅读(250)  评论(0)    收藏  举报