UVA 10382 Watering Grass 区间覆盖问题 -

这是一篇关于解决UVA 10382问题的博客,主要探讨如何使用贪心策略解决区间覆盖问题。作者首先介绍了问题背景,然后详细阐述了解决思路,包括对区间进行预处理,按起始点排序,从特定点开始选择最长区间等步骤。这个方法来源于刘汝佳的区间覆盖理论。
摘要由CSDN通过智能技术生成

题目地址:http://vjudge.net/problem/UVA-10382

第一想法:

1)ri*2<=w的去掉

2)肯定为了让决策有序化,按p排序

3)很明显 ,状态两种:开与不开,而且位置固定的,那么就可以看成由n个区间,求能覆盖整个区间的最小数量,那不是就贪心的区间覆盖问题嘛


思路来自,刘汝佳的区间覆盖:

1)预处理[a,b] 按照a的大小排列

2)从L点出发,把L左边的所有区间全部忽略

3)在从L点出发的区间里选一个最长的,R ,赋值L=R,如果没有L点出发的,表示无解

4)如果L<终点,继续2),否则返回,完成任务


#include <bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for(int i=a;i<=(b);++i)
#define REPD(i,a,b) for(int i=a;i>=(b);--i)
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
struct Aug
{
	double x1,x2;
	bool operator < (const Aug& p) const {
		return x1<p.x1;
	}
}A[10000+10];

int main(int argc, char const *argv[])
{
	int n;double l,w;
	while(scanf("%d%lf%lf",&n,&l,&w)==3){
		int cnt=0; double p,r;
		REP(i,1,n){
			scanf("%lf%lf",&p,&r);
			if(r*2<=w) continue;
			double s=sqrt(r*r-w*w/4);
			A[cnt++]=Aug{p-s,p+s};
		}
		sort(A,A+cnt);
		double L=0.0; int pos=0,ans=0;
		for(;;){
			REP(i,pos,cnt-1)   //以L为起点,所以去掉L左边的所有区间
			if(L>=A[i].x1) A[i].x1=L;
			else break;

			double R=0.0;  //在起点为L的中选个最长的
			if(pos<cnt&&L==A[pos].x1) while(pos<cnt&&L==A[pos].x1) R=max(R,A[pos].x2),pos++;
			else break;     //没有起点为L的表明无法完全覆盖
			if(R==0||L>=l) break; //已达终点就及时退出
			L=R; ans++;
		}
		printf("%d\n", L>=l?ans:-1);
	}
	return 0;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值