版权声明:本人原创文章若需转载请标明出处和作者!沙 https://blog.csdn.net/weixin_44143702/article/details/87815650
区间覆盖问题
Time Limit: 1000 ms Memory Limit: 65536 KiB
Problem Description
用i来表示x坐标轴上坐标为[i-1,i]的长度为1的区间,并给出n(1≤n≤200)个不同的整数,表示n个这样的区间。
现在要求画m条线段覆盖住所有的区间,
条件是:每条线段可以任意长,但是要求所画线段的长度之和最小,
并且线段的数目不超过m(1≤m≤50)。
Input
输入包括多组数据,每组数据的第一行表示区间个数n和所需线段数m,第二行表示n个点的坐标。
Output
每组输出占一行,输出m条线段的最小长度和。
Sample Input
5 3 1 3 8 5 11
Sample Output
7
做了几道贪心的题,发现贪心很多情况下就是需要找一些数据的最值,例如此题,就是找到最大间隔并进行删除,由此可见,日后在写贪心的题目时,可以多注意一下各个数据的最值。
#include <stdio.h>
#include <stdlib.h>
int a[205], b[205];
void quick_sort(int *, int, int);///由大到小快排
int main()
{
int n, m, i, Line_length, Line_number, j;
///线段的长度,线段的个数
while(~scanf("%d %d", &n, &m))
{
for(i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
quick_sort(a, 0, n - 1);///给 n 个区间降序排序,方便计算间隔距离
for(i = 0; i < n - 1; i++)
{///计算各区间间隔距离
b[i] = a[i] - a[i + 1] - 1;
}
quick_sort(b, 0, n - 2);///给 n - 1 个间隔距离排序,方便取最大间隔
Line_length = a[0] - a[n - 1] + 1;///当前情况下的长度
Line_number = 1;///当前的线段个数
j = 0;///记录间隔区间的位置
while(Line_number < m && b[j] > 0)
{///进行删减线段长度
Line_number++;///线段个数增加
Line_length -= b[j];///线段长度减少
j++;
}
printf("%d\n", Line_length);
}
return 0;
}
void quick_sort(int *a, int l, int r)
{///由大到小排序
int i, j, key;
i = l;
j = r;
key = a[i];
if(i >= j) return;
while(i < j)
{
while(i < j && a[j] <= key) j--;
a[i] = a[j];///由大到小排序应该跳过右方小的数据,将大数据移动到左边
while(i < j && a[i] >= key) i++;
a[j] = a[i];
}
a[i] = key;
quick_sort(a, l, i - 1);
quick_sort(a, i + 1, r);
}
此题的排序并未有特殊要求,此处我用的是快排,但是冒泡排序也可以。