poj3069:Saruman's Army
贪心策略
将整个问题分解成多个子问题,求每个子问题的最优解
先排序,最左端点右侧r范围内最远点选定为标记点,此后一个邻接点为下一个子问题最左端点
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 1000 + 10;
int pos[MAXN];
int main(){
int n, r;
while(scanf("%d%d", &r, &n) != EOF){
if(r == -1 && n == -1){
break;
}
for (int i = 0; i < n; ++i) {
scanf("%d", &pos[i]);
}
sort(pos, pos + n);
int k = 0;
int answer = 0;
while(k < n){
//寻找最左端的点右侧r范围内最远的点p
int s = pos[k++]; //子问题最左端的点
while(k < n && pos[k] <= s + r)
k++;
int p = pos[k-1];
//寻找超过p右侧r范围的第一个点,即下一个子问题的最左端点
while(k < n && pos[k] <= p + r)
k++;
answer++;
}
printf("%d\n", answer);
}
return 0;
}