区间覆盖问题
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
C++算法:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m,i,s;
int a[100];
int b[100];
while(cin>>n>>m)
{
for(i=0;i<n;i++)
{
cin>>a[i];
}
sort(a,a+n);//默认升序排序
s=a[n-1]-a[0]+1;//假设用一条线段把所有区间都覆盖了
for(i=0;i<n-1;i++)
{
b[i]=a[i+1]-a[i]-1;//把每个相邻的区间间隔作为另一个数组
}
sort(b,b+n-1);//默认升序排序
for(i=n-2;i>=n-m;i--)
{
s-=b[i];//逆向思维,总长度减去最大间隔即为题目所求
}
cout<<s<<endl;
}
return 0;
}
C语言算法:(原谅我没有用 i 而是用的 p )
#include <stdio.h>
#include <stdlib.h>
int main()
{
int p,q,t,n,m,s;
while(~scanf("%d %d",&n,&m))
{
int a[255]={0};
int b[255]= {0};
for(p=1; p<=n; p++)
{
scanf("%d",&a[p]);
}
for(p=1; p<n; p++)
{
for(q=p+1; q<=n; q++)
{
if(a[p]>a[q])
{
t=a[p];
a[p]=a[q];
a[q]=t;
}
}
}
s=a[n]-a[1]+1;
for(p=1; p<n; p++)
{
b[p]=a[p+1]-a[p]-1;
}
for(p=1; p<n-1; p++)
{
for(q=p+1; q<=n-1; q++)
{
if(b[p]>b[q])
{
t=b[p];
b[p]=b[q];
b[q]=t;
}
}
}
if(m>=n)
{
s=n;
}
else
{
for(p=n-1; p>n-m; p--)
{
if(m==1)
{
break;
}
s=s-b[p];
}
}
printf("%d\n",s);
}
return 0;
}