poj 2373 dp(灌溉草场)
来源:互联网 发布:高级算法工程师 编辑:程序博客网 时间:2024/06/05 00:49
题意:在一片草场上:有一条长度为L (1 <= L <= 1,000,000,L为偶数)的线 段。 John的N (1 <= N <= 1000) 头奶牛都沿着草场上这条线段吃草,每头 牛的活动范围是一个开区间(S,E),S,E都是整数。不同奶牛的活动范围可以 有重叠。
John要在这条线段上安装喷水头灌溉草场。每个喷水头的喷洒半径可以随 意调节,调节范围是 [A,B ](1 <= A <= B <= 1000),A,B都是整数。要求
线段上的每个整点恰好位于一个喷水头的喷洒范围内 每头奶牛的活动范围要位于一个喷水头的喷洒范围内 任何喷水头的喷洒范围不可越过线段的两端(左端是0,右端是L )
John要在这条线段上安装喷水头灌溉草场。每个喷水头的喷洒半径可以随 意调节,调节范围是 [A,B ](1 <= A <= B <= 1000),A,B都是整数。要求
线段上的每个整点恰好位于一个喷水头的喷洒范围内 每头奶牛的活动范围要位于一个喷水头的喷洒范围内 任何喷水头的喷洒范围不可越过线段的两端(左端是0,右端是L )
请问, John 最少需要安装多少个喷水头。
思路(参考郭炜老师课件):从线段的起点向终点安装喷水头,令f(X)表示:所安装喷水头的喷洒范围 恰好覆盖直线上的区间[0 X]时,最少需要多少个喷水头。显然,X应满足下列条件 1、X为偶数
2、X所在位置不会出现奶牛,即X不属于任何一个(S,E)
3、X≥2A
4、当X>2B时,存在Y∈[X-2B X-2A]且Y满足上述三个条件,使得 f(X)=f(Y)+1。由此得到
初始条件: f(X)=1: 2A≤X≤2B 、且X位于任何奶牛的活动范围之外;
状态转移方程:f(X)=1+min{f(Y): Y∈[X-2B X-2A]、Y位于任何奶牛的活动范围 之外}: X>2B。
关键在于快速找到[X-2B X-2A]中使得f(Y)最小的元素,有优先队列维护即可。注意stl优先队列用结构体类型的写法。
再有一点需要注意是如何快速判断一个点处是否有奶牛出没,而已在之前做一遍初始化,方法见代码。
#include <cstdio>#include <string>#include <queue>#include <iostream>#include <cstdlib>#include <cmath>#include <algorithm>#define INF 0x3fffffffusing namespace std;#define N 1000005#define INF 0x3fffffffstruct node{ int x,f; node(int xx=0,int ff=0):x(xx),f(ff){} bool operator<(const node &x) const { return f>x.f; }};priority_queue<node> q;int c[1005][2],dp[N],flag[N];int n,m,a,b;int main(){ int i,k; memset(flag, 0, sizeof(flag)); scanf("%d %d %d %d",&n,&m,&a,&b); for(i = 0;i<n;i++){ scanf("%d %d",&c[i][0],&c[i][1]); flag[c[i][0]+1]++;//为了判断一个点处是否有奶牛出没 flag[c[i][1]]--; } for(i = k = 0;i<=m;i++){ k += flag[i]; flag[i] = k>0;//说明有奶牛出没 dp[i] = INF; } a <<= 1; b <<= 1; for(i = a;i<=b;i+=2) if(!flag[i]){//如果没有奶牛 dp[i] = 1; if(b+2-a >= i)//在求F[i]的时候,要确保队列里的点x<= i - a q.push(node(i,1)); } for(i = b+2;i<=m;i+=2){ if(!flag[i]){ while(!q.empty()){ struct node tmp = q.top(); if(tmp.x < i-b){//范围之外的点直接剔除 q.pop(); continue; } dp[i] = tmp.f+1; break; } } if(dp[i+2-a] != INF)//队列中增加一个可达下个点的点 q.push(node(i+2-a,dp[i+2-a])); } if(dp[m] == INF) printf("-1\n"); else printf("%d\n",dp[m]); return 0;}
0 0
- poj 2373 dp(灌溉草场)
- POJ 2373 Dividing the Path(灌溉草场)
- poj2373 灌溉草场
- poj2373灌溉草场
- bzoj1986 [USACO2004 Dec] Dividing the Path 划区灌溉(dp+单调队列优化)
- 单调队列优化dp-----nkoj3662划区灌溉
- ccf 最优灌溉(prime模板)
- CCF201412-4 最优灌溉(80分)
- CCF之最优灌溉(java)
- 计蒜客-灌溉(java-prim算法)
- poj 1160(dp)
- Poj 2229(dp)
- Poj 2385 (dp)
- Poj 3616 (dp)
- Poj 3280(dp)
- Poj 2392(dp)
- Poj 1631(dp)
- poj 3267(dp)
- 去掉UITableView中多余空行
- 翻转二叉树
- 搭建scrapy抓取javascript动态数据的爬虫
- Android View的生命周期
- android客户端从服务器端获取json数据并解析
- poj 2373 dp(灌溉草场)
- Android4.2下 WebView的addJavascriptInterface漏洞解决方案
- FastCGI处理自定义HTTP头
- Java中的static关键字解析
- iOS开发之获取沙盒路径
- 使用surfaceview做一個簡單要骰子功能
- -Dmaven.multiModuleProjectDirectory system propery is not set.
- linux shell bash使用管道|和read结合时问题解决
- 记一次失败的面试