【BZOJ】【1986】【USACO 2004 Dec】/【POJ】【2373】划区灌溉
DP/单调队列优化
首先不考虑奶牛的喜欢区间,dp方程当然是比较显然的:$ f[i]=min(f[k])+1,i-2*b \leq k \leq i-2*a $ 当然这里的$i$和$k$都是偶数啦~这个应该很好理解吧……每次喷灌的都是一个偶数长度的区间嘛……
那么加上奶牛的喜欢区间的话,只需这样:当$ i>cow[j].x $时,令$ i=cow[j].y , j++$ 也就是说中间的位置全部不考虑放喷灌器。
显然我们对于每个节点的 k 是可以用单调队列维护的!嗯看到这里的同学可以先自己试着去写写看啦~
如果过了样例不要着急,来试试我这组数据:
2 16
2 4
7 8
6 12
Trick:
每个奶牛的喜欢区间是一个【开区间】!分界点是可以被不同的喷灌器灌溉的(仔细看看样例的图)
一开始英文题面嘛……看了中文没细看英文……没看到还有【不合法情况输出-1】so sad……
每个f[i]不能刚算出来就弹队尾+进队尾,因为此时下一个位置为 i+2 ,可能会把能够转移到i+2的合法状态弹出去,而f[i]是不能转移到f[i+2]的!(因为有a的限制)所以会造成f[i+2]计算错误(当然f[l]就也有可能出错了。
事实上由于我们维护的队列是一个合法状态区间,所以目前不合法的状态不应该进队,而是应该在每次更新f[i]之前让 f[i-2*a] 进队,这样可以保证队列中所有节点都为合法状态。
然而!!刚才那种做法会有漏洞!因为我们会在遇到奶牛的喜欢区间的时候跳!过!去!所以一些合法状态就会来不及进队(比如我给的数据中的f[6]……所以在遇到奶牛区间的时候要将这个区间内所有合法的状态进队(当然要维护队列单调性了……需要弹队尾)
/**************************************************************
Problem: 1986
User: Tunix
Language: C++
Result: Accepted
Time:40 ms
Memory:9092 kb
****************************************************************/ //POJ 2373
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
int getint(){
int v=,sign=; char ch=getchar();
while(ch<''||ch>''){ if (ch=='-') sign=-; ch=getchar();}
while(ch>=''&&ch<=''){ v=v*+ch-''; ch=getchar();}
return v*=sign;
}
const int N=1e6+,INF=~0u>>;
typedef long long LL;
/******************tamplate*********************/
//#define debug
struct Cow{
int x,y;
Cow(){}
bool operator < (const Cow &b)const{
return x<b.x || (x==b.x && y<b.y);
}
}cow[];
int f[N],n,l,a,b;
int q[N];
int main(){
#ifndef ONLINE_JUDGE
freopen("2373.in","r",stdin);
// freopen("2373.out","w",stdout);
#endif
n=getint(); l=getint(); a=getint(); b=getint();
F(i,,n) cow[i].x=getint(),cow[i].y=getint();
sort(cow+,cow+n+);
#ifdef debug
F(i,,n) printf("%d %d\n",cow[i].x,cow[i].y);
cout <<endl;
#endif
int j=;
F(i,,l) f[i]=INF;
int st=,ed=;
f[]=;
q[ed++]=;
for(int i=;i<=l;i+=){
while(i>cow[j].x && j<=n){
int last=i;
i=max(i,(cow[j].y+)/*),j++;
for(int I=last;I<=i;I+=)
if (f[I-*a]!=INF){
while(st<ed && f[q[ed-]]>f[I-*a]) ed--;
q[ed++]=I-*a;
}
}
while(st<ed && q[st]<i-*b) st++;
if(f[i-*a]!=INF){
while(st<ed && f[q[ed-]]>f[i-*a]) ed--;
q[ed++]=i-*a;
}
if (st<ed && i-q[st]>=*a) f[i]=f[q[st]]+;
}
#ifdef debug
F(i,,l) printf("%d ",f[i]==INF ? - : f[i]);
cout <<endl;
#endif
printf("%d\n",f[l]==INF ? - : f[l]);
return ;
}
【BZOJ】【1986】【USACO 2004 Dec】/【POJ】【2373】划区灌溉的更多相关文章
- BZOJ 4094 USACO 2013 Dec. Optimal Milking
线段树 每个节点保存4个值,both表示左右端点都取,neither表示左右端点都不取,left表示只取左端点,right表示只取右端点. 维护的特殊姿势: $cur$的$both=max(ls.l+ ...
- BZOJ 1606 USACO 2008 Dec. 购买干草
[题意概述] 有n件物品,每件物品有体积Vi,背包容量为C,问最多可以装多少体积的物品 [题解] 显然是个无限背包嘛.. 直接做背包DP就好 注意无限背包的写法和01背包的区别 #include< ...
- BZOJ1986: [USACO2004 Dec] Dividing the Path 划区灌溉
L<=1000000的土地上用长度在2*A~2*B的线段覆盖所有点,且给定n<=1000个区间,每个区间上只允许有一条线段,求最少多少线段,无解-1. f[i]表示填前i个土地最少线段,f ...
- 【Noip模拟 20160929】划区灌溉
题目描述 约翰的奶牛们发现山脊上的草特别美味.为了维持草的生长,约翰打算安装若干喷灌器. 为简化问题,山脊可以看成一维的数轴,长为L(1≤L≤1,000,000)L(1≤L≤1,000,000),而且 ...
- [POJ 2373][BZOJ 1986] Dividing the Path
Link: POJ 2373 传送门 Solution: 一开始想错方向的一道简单$dp$,不应该啊…… 我一开始的想法是以$cows' ranges$的节点为状态来$dp$ 但明显一个灌溉的区间的两 ...
- USACO翻译:USACO 2013 DEC Silver三题
USACO 2013 DEC SILVER 一.题目概览 中文题目名称 挤奶调度 农场航线 贝西洗牌 英文题目名称 msched vacation shuffle 可执行文件名 msched vaca ...
- USACO翻译:USACO 2014 DEC Silver三题
USACO 2014 DEC SILVER 一.题目概览 中文题目名称 回程 马拉松 奶牛慢跑 英文题目名称 piggyback marathon cowjog 可执行文件名 piggyback ma ...
- poj 2373 Dividing the Path
Dividing the Path Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2858 Accepted: 1064 ...
- bzoj:1675 [Usaco2005 Feb]Rigging the Bovine Election 竞选划区
Description It's election time. The farm is partitioned into a 5x5 grid of cow locations, each of wh ...
随机推荐
- Windows7防火墙服务无法启用怎么办
点击windows 7控制面板中防火墙的“推荐配置”没有反应,打开“服务”,无法启动windows firewall,并报错. 问题: 1.点击windows 7控制面板中防火墙的“推荐配置”没有 ...
- 自定义获取html元素对象的7种方法。
- jQuery学习笔记(3)
children():只考虑子元素而不考虑其他后代元素 <html xmlns="http://www.w3.org/1999/xhtml"> <head run ...
- 解决在sublime text3在ubuntu下无法输入中文的问题
方法链接:https://github.com/lyfeyaj/sublime-text-imfix 效果图:
- Python生成器以及yield语句
生成器是一种暂缓求值的技术,它可以用来生成一系列的值,但不会一次性生成所有的值,而只在需要的时候才计算和生成一个值. 通过yield语句构建生成器 要得到一个生成器,我们需要定义一个函数,这个函数返回 ...
- java中的排序
排序是数据结构中重要的一个部分,也是在实际开发中最易遇到的问题之一,当然了,你也可以不考虑这些排序的算法,直接把要排序的数据insert到数据库中,用数据库的order by再select一下,也能产 ...
- Microsoft SqlServer2008技术内幕:T-Sql语言基础-读书笔记1
一.理论背景:关系模型,其数学理论是集合论和谓词逻辑. 1.集合论:集合定义是把我们直观或思维中确定的,相互间有明确区别的那些对象视为一个整体,这个整体就是集合. 2.谓词逻辑:谓词是判断对象是否有某 ...
- DB2物化表
DB2物化查询表(MQT)是DB2数据库中一类特殊的表 物化表和视图的区别 物化表是一个查询结果集,视图是一个SQL语句. 以下是一个简单例子(说明物化表) 1.创建表,插入测试数据 ----创建表 ...
- oh-my-zsh配置你的zsh提高shell逼格终极选择
抱歉,这篇博文推迟发布了,人都是有惰性的...看在这个牛逼闪闪的标题就原谅我吧! 为何这篇文章要归类到 mac 下? 第一个问题,稍后我们说明下. zsh是个什么东东? 第二个问题... 你应该稍微接 ...
- C++ STL vector 内存分配
vector为了支持快速的随机访问,vector容器的元素以连续方式存放,每一个元素都紧挨着前一个元素存储. 当vector添加一个元素时,为了满足连续存放这个特性,都需要重新分配空间.拷贝元素.撤销 ...