洛谷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。
解题思路:
- 排序+贪心
- 假设每一个坑都被管制了,但是由于管制的路段数量有限,所以就要减去尽可能大的没有坑路段,然后得出的就是答案了。
贪心问题需要证明:
题目要求实施交通管制的路段总长度最短,我们就必须使管制的路段中被浪费的长度尽量小。因为只有坑所在的点才需要被维护,这里“被浪费的长度”,其实就是坑与坑之间的距离 ,即没有被管制的路段。
显然可以得出结论: 所有被管制路段的的开头和结尾一定都在坑上, 才能使浪费达到最小。所以我们需要考虑的其实是从第一个坑到第n个坑的范围,道路的头尾两端都可以省略。
那么问题就来了,在怎么在第一个坑和最后一个坑之间管制m个路段,使总浪费最小呢?
我们可以注意到,根据刚才得出的结论,在这m条路段中,第一条的开头一定是第一个坑,而第m条路段的结尾一定是第n个坑。每两个管制路段之间会有一个没有被管制的路段,所以,在第一个坑和第n个坑之间,
一共会有m-1个没有被管制的路段,即会有m-1“坑与坑之间的距离”会被浪费。
为了使浪费最短,我们就可以用sort对每两个坑之间的距离进行排序,然后用第一个坑到第n个坑之间的距离依次减去前m−1个最 长的没有坑的路段,就可以求出答案了。
参考代码:
#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;
}

浙公网安备 33010602011771号