题述
直线上有N个点。点i的位置是Xi。从这N个点中选择若干个,给它们加上标记。对每一个点,其距离为R内的区域里必须有带有标记的点(自己本身带有标记的点,可以认为与其距离为零的地方有一个带有标记的点)。在满足这个条件的情况下,希望能尽可能少的点添加标记。请问至少要有多少点被加上标记?
限制条件
1<=N<=1000
0<=R<=1000
0<=Xi<=1000
题记
怎么样找被标记的点呢?贪心算法可以很好的解决,我们就从最左边开始(第一个没有被覆盖的点,显然第一个点在我们没有添加任何一个标记的时候是没有被覆盖的),一直找直到找到R以内最远的那个点,这个点就是我们要找的标记点,它的右边有一部分就被标记了,我们还要向右找一个边界,就是第一个超出最新标记点覆盖范围的那个点,这样像当前操作步骤一样循环就行了。
代码如下
#include <iostream>
using namespace std;
const int Maxn=1005;
//输入
int N,R;
int X[Maxn];
void solve(){
int i=0,ans=0;
while(i<N){
//s是没有覆盖的最左边的点
int s=X[i];
//找到右边第一个超出R的点
while(i<N&&X[i]<=s+R)i++;
//左半部分最靠右的点(这个点就是要添加标记的点)
int p=X[i-1];
//再接着向右直到超出R的第一个点
while(i<N&&X[i]<=p+R)i++;
ans++;
}
printf("%d\n",ans);
}
int main()
{
scanf("%d %d",&N,&R);
for(int i=0;i<N;i++)
scanf("%d",&X[i]);
solve();
return 0;
}