Link:

POJ 2373 传送门

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的更多相关文章

  1. POJ 2373 Dividing the Path(DP + 单调队列)

    POJ 2373 Dividing the Path 描述 农夫约翰的牛发现,在他的田里沿着山脊生长的三叶草是特别好的.为了给三叶草浇水,农夫约翰在山脊上安装了喷水器. 为了使安装更容易,每个喷头必须 ...

  2. poj 2373 Dividing the Path

    Dividing the Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2858   Accepted: 1064 ...

  3. poj2373 Dividing the Path

    Dividing the Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5060   Accepted: 1782 ...

  4. 【POJ】2373 Dividing the Path(单调队列优化dp)

    题目 传送门:QWQ 分析 听说是水题,但还是没想出来. $ dp[i] $为$ [1,i] $的需要的喷头数量. 那么$ dp[i]=min(dp[j])+1 $其中$ j<i $ 这是个$ ...

  5. Dividing the Path POJ - 2373(单调队列优化dp)

    给出一个n长度的区间,然后有一些小区间只能被喷水一次,其他区间可以喷水多次,然后问你要把这个区间覆盖起来最小需要多少喷头,喷头的半径是[a, b]. 对于每个只能覆盖一次的区间,我们可以把他中间的部分 ...

  6. Dividing the Path POJ - 2373 dp

    题意:你有无数个长度可变的区间d  满足 2a<=d<=2b且为偶数. 现在要你用这些区间填满一条长为L(L<1e6且保证是偶数)的长线段. 满足以下要求: 1.可变区间之间不能有 ...

  7. POJ 2373 Dividing the Path (单调队列优化DP)题解

    思路: 设dp[i]为覆盖i所用的最小数量,那么dp[i] = min(dp[k] + 1),其中i - 2b <= k <= i -2a,所以可以手动开一个单调递增的队列,队首元素就是k ...

  8. HDU 3062 && HDU 1824 && POJ 3678 && BZOJ 1997 2-SAT

    一条边<u,v>表示u选那么v一定被选. #include <iostream> #include <cstring> #include <cstdio> ...

  9. [USACO2004][poj2373]Dividing the Path(DP+单调队列)

    http://poj.org/problem?id=2373 题意:一条直线分割成N(<=25000)块田,有一群奶牛会在其固定区域吃草,每1把雨伞可以遮住向左右延伸各A到B的区域,一只奶牛吃草 ...

随机推荐

  1. 【非原创】tomcat 安装时出现 Failed to install Tomcat7 service

    tomcat 安装时出现 Failed to install Tomcat7 service 今天在安装tomcat时提示 Failed to install Tomcat7 service了,花了大 ...

  2. .Net MVC断点进不去

    .Net MVC断点进不去 1.httpget  httppost 2.启动项设为UI 3.基于页面没错误的情况下

  3. hadoop2.6.4【windows7】构建maven项目 系列2

    准备windows版本的hadoop2.6.4 下载windows版本的hadoop2.6.4解压在本地 新建maven项目构建hadoop依赖 <?xml version="1.0& ...

  4. Java String.intern()_学习笔记

    参考:https://www.jianshu.com/p/0d1c003d2ff5 String.intern() String.intern()是native方法,底层调用c++中的StringTa ...

  5. P2029 跳舞

    题目描述 小明今天得到一个跳舞毯游戏程序Dance.游戏每次连续出N个移动的“箭头”,箭头依次标号为1到N,并且的相应的分数S[1..N].如果你能“踏中”第i号箭头,你将获得相应的分数S[i]:否则 ...

  6. Custom LDAP Monitor Does Not Work

    Custom LDAP Monitor Does Not Work https://www.poppelgaard.com/netscaler-case-study-custom-ldap-monit ...

  7. POJ 3090 Visible Lattice Points | 其实是欧拉函数

    题目: 给一个n,n的网格,点可以遮挡视线,问从0,0看能看到多少点 题解: 根据对称性,我们可以把网格按y=x为对称轴划分成两半,求一半的就可以了,可以想到的是应该每种斜率只能看到一个点 因为斜率表 ...

  8. linux下源代码分析和阅读工具比较

    Windows下的源码阅读工具Souce Insight凭借着其易用性和多种编程语言的支持,无疑是这个领域的“带头大哥”.Linux/UNIX环境下呢?似乎仍然是处于百花齐放,各有千秋的春秋战国时代, ...

  9. 【POJ 3080 Blue Jeans】

    Time Limit: 1000MSMemory Limit: 65536K Total Submissions: 19026Accepted: 8466 Description The Genogr ...

  10. bzoj1264 [AHOI2006]基因匹配Match 树状数组+lcs

    1264: [AHOI2006]基因匹配Match Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1255  Solved: 835[Submit][ ...