Dividing the Path

D i v i d i n g   t h e   P a t h Dividing\ the\ Path Dividing the Path

题目链接:POJ 2373

题目大意

在长为 L L L的草地(可看成线段)上装喷水头,喷射是以这个喷水头为中心,喷水头的喷洒半径是可调节的,调节范围为 [ a , b ] [a,b] [a,b]。要求草地的每个点被且只被一个喷水头覆盖,并且有些连续区间 [ s , e ] [s,e] [s,e]必须被某一个喷水头覆盖而不能由多个喷头分段完全覆盖,求喷水头的最小数。

样例输入

2 8
1 2
6 7
3 6

样例输出

3

样例解释

沿着长度为 8 8 8的草地的两头母牛。喷头的整数喷雾半径范围为 1..2 1..2 1..2(即 1 1 1 2 2 2)。一头牛喜欢 3 − 6 3-6 36的范围,另一头喜欢 6 − 7 6-7 67的范围。

需要三个洒水喷头:一个喷涂距离为 1 1 1,喷涂距离为 1 1 1,喷涂距离为 1 1 1,喷涂距离为 1 1 1,喷涂距离为 1 1 1,喷涂距离为 1 1 1,第二喷头浇水范围内的所有三叶草(如第二头奶牛) 3 − 6 3-6 36)。最后一个喷水器浇灌了第一头牛( 6 − 7 6-7 67)喜欢的所有三叶草。这是一个图表:
                                                             ∣ − − − − − c 2 − − − − ∣ − c 1 ∣                                c o w s ′ p r e f e r r e d r a n g e s \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |-----c2----|-c1|\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ cows' preferred ranges                                                             c2c1                              cowspreferredranges
       ∣ − − − − 1 − − − ∣ − − − − − − − − 2 − − − − − − − ∣ − − − − 3 − − − ∣         s p r i n k l e r s \ \ \ \ \ \ |----1---|--------2-------|----3---|\ \ \ \ \ \ \ sprinklers       123       sprinklers
      + − − − + − − − + − − − + − − − + − − − + − − − + − − − + − − − + \ \ \ \ \ +---+---+---+---+---+---+---+---+      +++++++++
      0                 1                2                3                4                5                6                7                8 \ \ \ \ \ 0\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 1\ \ \ \ \ \ \ \ \ \ \ \ \ \ 2\ \ \ \ \ \ \ \ \ \ \ \ \ \ 3\ \ \ \ \ \ \ \ \ \ \ \ \ \ 4\ \ \ \ \ \ \ \ \ \ \ \ \ \ 5\ \ \ \ \ \ \ \ \ \ \ \ \ \ 6\ \ \ \ \ \ \ \ \ \ \ \ \ \ 7\ \ \ \ \ \ \ \ \ \ \ \ \ \ 8      0               1              2              3              4              5              6              7              8

数据范围

1 &lt; = N &lt; = 1000 1&lt;=N&lt;=1000 1<=N<=1000
1 &lt; = L &lt; = 1 , 000 , 000 1 &lt;= L &lt;= 1,000,000 1<=L<=1,000,000
1 &lt; = A &lt; = B &lt; = 1000 1 &lt;= A &lt;= B &lt;= 1000 1<=A<=B<=1000
0 &lt; = S &lt; E &lt; = L 0 &lt;= S &lt; E &lt;= L 0<=S<E<=L

思路

这道题就是一道 d p dp dp
我们先判定一下,因为浇水的长度一定是双数,所以如果是单数,就一定不能浇完。
然后,我们设 f [ i ] f[i] f[i] [ 0 , i ] [0,i] [0,i]区间需要多少喷头。
然后再判定一下特殊区间的情况就可以了。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n, l, a, b, f[1000001], q[1000001], h, t, size, x, y;
int main()
{
	scanf("%d%d%d%d", &n, &l, &a, &b);//读入
	if (l&1) {return 0; printf("-1");}//判断是否可以完全覆盖
	for (int i = 1; i <= n; i++)
	{
		scanf("%d%d", &x, &y);//读入
		for (int j = x + 1; j < y; j++)
			f[j] = 1000000001;
	}
	f[0] = 0;//初始化
	size = 2 * b - 2 * a;//初始化
	for (int i = 2; i < 2 * a; i += 2)
		f[i] = 1000000001;//初始化
	for (int i = 2 * a; i <= l; i += 2)
	{
		 while (h < t && f[q[t - 1]] >= f[i - 2 * a]) t--;//从后往前插入
		 q[t++] = i - 2 * a;//入队
		 while (i - 2 * a - q[h] > size) h++;//找可选区间
		 if (f[i] <= 1000000000)
		 	f[i] = f[q[h]] + 1;//dp
	}
	if (f[l] >= 1000000000) printf("-1");//做不到
		else printf("%d", f[l]);//输出
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值