1.题目
区间覆盖问题
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
Hint
注意:题目数据已于2018.4.16更新
2.正确代码
#include <algorithm>
#include <iostream>
using namespace std;
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
int m,n,i,a[100001],b[100001],des;
while(cin >> m >> n)
{
for(i=1;i<=m;i++)
cin >> a[i];
sort(a+1,a+m+1);
des=a[m]-a[1]+1;
for(i=1;i<=m-1;i++)
b[i]=a[i+1]-a[i]-1;
sort(b+1,b+m,cmp);
for(i=1;i<=n-1;i++)
{
des-=b[i];
}
cout << des << endl;
}
return 0;
}
3.题目解读:
1.这个算法很简单,我们并不是采用“加法思想”,而是采用“减法思想”,我们每次减去差值最大的。
2.如上所述,这个问题就简化成排序问题了,思路还是比较清楚的。
3.但你应该注意,这里线段的差值和个数都存在“+1.-1”的问题,同时,你在使用sort()
函数,因为你从1开始的,所以你排序应该写为sort(a+1,a+n+1)
,明确排序个数在这个问题上你不要弄混了!