贪心算法-Aaruman's Army

Saruman’s Army

直线上有N个点。点X的位置是Xi。从这N个点中选中若干个点,给它们添加上标记。对每一个点,其距离为R以内的区域里必须有带有标记的点(自己本身带有标记的点,可以认为与其距离为0的地方有一个带有标记的点)。在满足这个条件的情况下,希望能够为尽可能少的点添加标记?
限制条件:
1<=N<=1000
0<=R<=1000
0<=Xi<=1000

输入示例:
N=6
R=10
X={1,7,15,20,30,50}

输出示例:
3

思路:
第一步,我们可以从最左边一个点开始考虑,最左边的点的右边距离为R的区域里必须有一个被标记的点,那么我们选取哪个点呢?为了尽可能少的标记点,显然,我们选区在R内最靠右的点。

这里写图片描述

第二步,以刚才标记的点为起点,向右标记标记距离R以外的第一个点。

这里写图片描述

第三步,不断重复第二步过程……

代码如下:

//Saruman's Army


#include<iostream>
#define MAX_N 1000
using namespace std;

int N ,R ; //N表示点个数,R距离
int X[MAX_N];//X保存每个点的位置
bool point[MAX_N];
void init(){
    cin>>N>>R;
    for(int i=0;i<N;i++){
        cin>>X[i];
    }
}

void solve(){
    int temp;
    for(int i=1;i<N;i++){ //步骤一,找到第一个标记的点
        if( (X[i]-X[0]) >=R){
            point[i-1]=false;
            temp=i;
            break;
        }
    }
    while(temp<N){   //循环操作步骤二
        int i=temp;
        i++;
        if( (X[i]-X[temp]) <X[i] ){
            temp=i;
            point[i]=true;
        }
    }

    int count=0;   //统计标记点的个数
    for(int i=0;i<N;i++){
        if(point[i]) count++; 
    }
    cout<<count<<endl;
}

int main(){
    init();
    solve();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_28120673/article/details/81022253
今日推荐