UPC-6199 LCYZ的道路(贪心)

题目描述
由于在修新教学楼,LCYZ的路上出现了N个坑。为了尽快填补好这N个坑,LCYZ决定对M处地段采取封闭措施。为了求解方便,假设LCYZ的路只有一条,而且是笔直的。现在给出N个坑的位置,请你计算,最少要对多远的路段采取封闭措施?

输入
输入数据共两行,第一行为两个正整数N、M (2<=N<=15000,M<=N)。第二行给出了N个坑的坐标(坐标值均在int范围内,按从小到大的顺序给出,且不会有两个点坐标相同)。
输出
仅一行,为最小长度和。
样例输入
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。

一开始以为是经典的二分修路,后来发现就是简单的贪心,直接把路段每一段间距算出来,然后取m-1个最长的 间隔,在总间隔(n-1)这段长度中减去m-1段最长的间隔,剩下来的就是最短选择封闭的地段。想想很好理解,我们如果选分成1整段路,那么中间肯定会存在很多较长的空隙,这些(m-1段)空隙减掉,就将一整段路分成了m段,注意代码中如何计算边界,也就是减去空隙时,我们要留下空隙的端点。
对整段路做长度计算时,我们要加上被减去的左端点。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[16000];
bool cmp(int a,int b)
{
    return a>b;
}
int main()
{
    int n,m,dis[16000];
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int j=0,ans=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            if(i!=1)dis[j++]=a[i]-a[i-1];
        }
        ans=a[n]-a[1]+1;
        sort(dis,dis+j,cmp);
//        for(int i=0;i<j;i++)printf("%d%c",dis[i],i==j-1?'
':' ');
        for(int i=0;i<m-1;i++) ans=ans-dis[i]+1;
        printf("%d
",ans);
    }
}
原文地址:https://www.cnblogs.com/kuronekonano/p/11135808.html