[POJ 2373][BZOJ 1986] Dividing the Path
Link:
Solution:
一开始想错方向的一道简单$dp$,不应该啊……
我一开始的想法是以$cows' ranges$的节点为状态来$dp$
但明显一个灌溉的区间的两边不一定都在$cows's ranges$上,
因此应该以长为$L$的$field$上的每一个偶数节点为状态来$dp$,
这样转移方程就很容易了:
$dp[i]=min\{ dp[j] \} +1(2*a\le i-j\le 2*b)$
由于$dp[j]$具有决策单调性(对于节点$i$,$k$比$j$更优$(j<k)$,那么对于后面任意一个节点$j$都优于$k$)
于是使用单调队列维护一个$dp$值递增,离起点距离递增的序列,每次弹出$i-q[l]>=2*b$的$l$
为了处理$cows' ranges$上的节点,使用差分将在区间内的节点打上标记,遇到时跳过即可
Note:这里的特判依然要注意,如果对于一个非终点的节点找不到符合的点,不代表无解!跳过即可
Code:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring> using namespace std;
const int MAXN=1e6+; int n,L,a,b,dp[MAXN],pre[MAXN],q[MAXN],l,r; int main()
{
scanf("%d%d%d%d",&n,&L,&a,&b);
for(int i=;i<=n;i++)
{
int x,y;scanf("%d%d",&x,&y);
pre[x+]++;pre[y]--;
if(y-x>*b){printf("-1");return ;}
}
for(int i=;i<=L;i++) pre[i]+=pre[i-]; l=r=;q[]=;
for(int i=*a;i<=L;i+=)
{
if(pre[i]) continue;
while(l<=r && i-q[l]>*b) l++;
if(l>r){printf("-1");return ;}
if(i-q[l]<*a) continue; //对不符合条件的数的处理 dp[i]=dp[q[l]]+;
while(l<=r && dp[i]<dp[q[r]]) r--;q[++r]=i;
}
if(!dp[L]) printf("-1"); //特例处理
else printf("%d",dp[L]);
return ;
}
Review:
(1)还是要对特判细节想清楚啊……
(2)对于有决策单调性的题目想到单调性优化
(3)选择$dp$状态时要考虑状态集是否包含了所有“过程”中的“终点”
(如果按$cows' ranges$选取则不能)
[POJ 2373][BZOJ 1986] Dividing the Path的更多相关文章
- POJ 2373 Dividing the Path(DP + 单调队列)
POJ 2373 Dividing the Path 描述 农夫约翰的牛发现,在他的田里沿着山脊生长的三叶草是特别好的.为了给三叶草浇水,农夫约翰在山脊上安装了喷水器. 为了使安装更容易,每个喷头必须 ...
- poj 2373 Dividing the Path
Dividing the Path Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2858 Accepted: 1064 ...
- poj2373 Dividing the Path
Dividing the Path Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5060 Accepted: 1782 ...
- 【POJ】2373 Dividing the Path(单调队列优化dp)
题目 传送门:QWQ 分析 听说是水题,但还是没想出来. $ dp[i] $为$ [1,i] $的需要的喷头数量. 那么$ dp[i]=min(dp[j])+1 $其中$ j<i $ 这是个$ ...
- Dividing the Path POJ - 2373(单调队列优化dp)
给出一个n长度的区间,然后有一些小区间只能被喷水一次,其他区间可以喷水多次,然后问你要把这个区间覆盖起来最小需要多少喷头,喷头的半径是[a, b]. 对于每个只能覆盖一次的区间,我们可以把他中间的部分 ...
- Dividing the Path POJ - 2373 dp
题意:你有无数个长度可变的区间d 满足 2a<=d<=2b且为偶数. 现在要你用这些区间填满一条长为L(L<1e6且保证是偶数)的长线段. 满足以下要求: 1.可变区间之间不能有 ...
- POJ 2373 Dividing the Path (单调队列优化DP)题解
思路: 设dp[i]为覆盖i所用的最小数量,那么dp[i] = min(dp[k] + 1),其中i - 2b <= k <= i -2a,所以可以手动开一个单调递增的队列,队首元素就是k ...
- HDU 3062 && HDU 1824 && POJ 3678 && BZOJ 1997 2-SAT
一条边<u,v>表示u选那么v一定被选. #include <iostream> #include <cstring> #include <cstdio> ...
- [USACO2004][poj2373]Dividing the Path(DP+单调队列)
http://poj.org/problem?id=2373 题意:一条直线分割成N(<=25000)块田,有一群奶牛会在其固定区域吃草,每1把雨伞可以遮住向左右延伸各A到B的区域,一只奶牛吃草 ...
随机推荐
- Yapi的坑
前一段时间,研究WEB Api相关的工具. YApi 可以内网部署,内心十分的欢喜啊.而且gitHub上推荐超过4000星,成绩很优异嘛.然而通过最终的尝试,我还是打算放弃他,投入Postman的怀抱 ...
- 孤荷凌寒自学python第五十八天成功使用python来连接上远端MongoDb数据库
孤荷凌寒自学python第五十八天成功使用python来连接上远端MongoDb数据库 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第四天.今天的感觉是,mongoDB数据 ...
- QQ网页强制聊天,微博一键关注
<!doctype html> <!-- 微博关注需要的js --> <html xmlns:wb="http://open.weibo.com/wb" ...
- [DM8168]Linux下SPI驱动测试
1.内核自带的SPI相关的驱动文件 项目中有CPU与FPGA进行通信,用到SPI接口: SPI头文件在: linux-kernel/include/linux/spi.h SPI实现在: linux- ...
- shell之小知识点
last:显示/var/log/wtmp文件,显示用户登录历史及重启历史 -n #:仅显示最近几次的相关信息 lastb:/var/log/btmp文件,显示用户错误的登录尝试 -n ...
- 九宫重排_康拓展开_bfs
历届试题 九宫重排 时间限制:1.0s 内存限制:256.0MB 问题描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可 ...
- 浅谈数据库系统中的cache(转)
http://www.cnblogs.com/benshan/archive/2013/05/26/3099719.html 浅谈数据库系统中的cache(转) Cache和Buffer是两个不同 ...
- java 图形化界面笔记(1)
目录 JFrame窗体......................................................................................... ...
- [bzoj] 1176 Mokia || CDQ分治
原题 给出W×W的矩阵(S没有用,题目有误),给出无限次操作,每次操作的含义为: 输入1:你需要把(x,y)(第x行第y列)的格子权值增加a 输入2:你需要求出以左下角为(x1,y1),右上角为(x2 ...
- POJ 2186 受欢迎的牛 Tarjan基础题
#include<cstdio> #include<algorithm> #include<cstring> #include<vector> #inc ...