贪心(2)区间选点问题

来源:互联网 发布:如何撰写数据分析报告 编辑:程序博客网 时间:2024/05/03 14:13

选自刘汝佳白皮书

问题描述:数轴上有n个闭区间[ai,bi].取尽量少的点,使得每个区间内都至少有一个点(不同区间内含的点可以是同一个)。

分析:

如果区间i内已经有一个点被取到,我们称此区间已经被满足。受到贪心(1)的启发,我们先讨论区间包含的情况。由于小区间被满足时,大区间一定被满足。所以在区间包含的情况下,大区间不需要考虑。

把所有区间按b从小到大排序(b相同时a从大到小排序),则如果出现区间包含的情况,小区间一定排在前面,第一个区间应该取哪一个点呢?贪心策略是:取最后一个点。

因为取最后一个点能最大可能性的使得下个区间被满足;

经典例题:http://acm.nyist.net/JudgeOnline/problem.php?pid=287

这道题思路是每一个海岛都对应着x轴上的一个区间,那么就有n个区间,就转化成了区间选点问题了

Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. Each small island is a point locating in the sea side. And any radar installation, locating on the coasting, can only cover d distance, so an island in the sea can be covered by a radius installation, if the distance between them is at most d. 

We use Cartesian coordinate system, defining the coasting is the x-axis. The sea side is above x-axis, and the land side below. Given the position of each island in the sea, and given the distance of the coverage of the radar installation, your task is to write a program to find the minimal number of radar installations to cover all the islands. Note that the position of an island is represented by its x-y coordinates.

 

输入
The input consists of several test cases. The first line of each case contains two integers n (1<=n<=1000) and d, where n is the number of islands in the sea and d is the distance of coverage of the radar installation. This is followed by n lines each containing two integers representing the coordinate of the position of each island. Then a blank line follows to separate the cases. 

The input is terminated by a line containing pair of zeros
输出
For each test case output one line consisting of the test case number followed by the minimal number of radar installations needed. "-1" installation means no solution for that case.
样例输入
3 21 2-3 12 11 20 20 0
样例输出
Case 1: 2Case 2: 1
附上代码: 

#include <iostream>#include <stdio.h>#include <string.h>#include <string>#include <algorithm>#include <cmath>using namespace std;struct node{ double x; double y;}a[1100];int cmp(node a,node b){  if(a.y!=b.y)    return a.y<b.y;  return a.x>b.x;}int main(){ int n,d,flag,test=0; while(cin>>n>>d) {  if(n==0&&d==0)break;  flag=1;  test++;  double l,r;  for(int i=0;i<n;i++)    {     cin>>l>>r;     if(d<=0||d<r)     {      flag=0;      break;     }     a[i].x=l-sqrt(d*d-r*r);     a[i].y=l+sqrt(d*d-r*r);    }  if(!flag)  {   cout<<-1<<endl;   continue;  }  sort(a,a+n,cmp);  int cnt=1;  double s=a[0].y;  for(int i=1;i<n;i++)  {    if(a[i].x>s)    {      cnt++;      s=a[i].y;    }  }  printf("Case %d: %d\n",test,cnt); } return 0;}




0 0
原创粉丝点击