POJ 2373
原本一道挺简单的DP题,思路有了,运用单调队列,但在写单调队列时写挫了。。。
这道题只需要计算偶数位置的即可,这是显而易见的,我有注意过这情况,写的时候却没在意。。。--!
加入队列的元素应该当前now之前的now-2*A的元素,我开始不是每计算一个now位置就加入now-2*A的元素,搞得不是O(L)的复杂度。这次吸取教训了。。记得DP时使用单调队列一般每计算一个位置加入一个元素。
PS:
又回想起之前比赛,感觉很害怕。。希望自己加油吧。
我的代码:不知为何没能过。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#include <string.h>
#include <queue>
#include <cmath>
#include <vector> using namespace std;
const int N=1000100;
const int inf=1<<30; int dp[N],que[N],f,l,p;
struct Node{
int l,r;
Node(){l=0,r=0;}
Node(int ll,int rr){l=ll,r=rr;}
bool operator <(const Node &a)const{
if(l<a.r) return true;
return false;
}
};
Node node[1010]; int n,L,a,b; void Mergeinter(){
/* int top=0;
for(int i=1;i<n;i++){
if(node[i].l<node[top].r&&node[top].r<node[i].r)
node[top].r=node[i].r;
else if(node[i].l<node[top].r&&node[top].r>=node[i].r) continue;
else{
top++;
node[top].l=node[i].l;
node[top].r=node[i].r;
}
}
n=top;*/
int top=0;
int l=node[0].l,r=node[0].r;
for(int i=1;i<n;i++){
if(node[i].l<r){
r=max(r,node[i].r);
}else{
node[top++]=Node(l,r);
l=node[i].l;
r=node[i].r;
}
}
node[top++]=Node(l,r);
n=top;
} void Pop(int now){
while(f<l){
if(now-que[f]<=b) break;
f++;
}
} void Push(int now){
while(f<l){
if(dp[que[l-1]]<dp[now-a]) break;
l--;
}
que[l++]=now-a;
} int main(){
while(scanf("%d%d",&n,&L)!=EOF){
scanf("%d%d",&a,&b);
for(int i=0;i<n;i++){
scanf("%d%d",&node[i].l,&node[i].r);
}
if(L%2==1){ printf("-1\n");continue; }
f=l=p=0;
sort(node,node+n);
Mergeinter();
a*=2;b*=2;
dp[0]=0;
for(int i=2;i<a;i+=2) dp[i]=inf;
for(int i=a;i<=L;i+=2){
Pop(i);
Push(i);
while(p<n&&node[p].r<=i) p++;
if(p<n&&node[p].l<i||dp[que[f]]==inf) dp[i]=inf;
else dp[i]=dp[que[f]]+1;
}
if(dp[L]==inf) printf("-1\n");
else printf("%d\n",dp[L]);
}
return 0;
}
引用别人的:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;
const int MAX=1001000;
const int oo=0x3f3f3f3f;
int dp[MAX];
struct Seg{
int x,y;
Seg(int x=0,int y=0):x(x),y(y){}
bool operator<(const Seg& seg) const{
return x<seg.x;
}
}seg[1100];
int q[MAX],id[MAX],f,b;
int merge(int n){
int top=0;
sort(seg,seg+n);
int l=seg[0].x,r=seg[0].y;
for(int i=1;i<n;i++){
if(seg[i].x<r){
r=max(r,seg[i].y);
}else{
seg[top++]=Seg(l,r);
l=seg[i].x;
r=seg[i].y;
}
}
seg[top++]=Seg(l,r);
return top;
}
int main(){
int n,L,l,r,p;
scanf("%d%d",&n,&L);
if(L&1){
printf("%d\n",-1);
return 0;
}
scanf("%d%d",&l,&r);
for(int i=0;i<n;i++){
scanf("%d%d",&seg[i].x,&seg[i].y);
}
n=merge(n);
l<<=1;
r<<=1;
dp[0]=0;
f=b=0;
p=0;
dp[0]=0;
for(int i=2;i<l;i+=2)dp[i]=oo; //start with 2.
for(int i=l;i<=L;i+=2){
while(f!=b&&i-id[f]>r)f++;
while(f!=b&&q[b-1]>=dp[i-l])b--;
id[b]=i-l;
q[b++]=dp[i-l];
while(p<n&&seg[p].y<=i)p++;
if(p<n&&seg[p].x<i||q[f]==oo)dp[i]=oo; //if q[f] is oo, not to set dp[i] = q[f]+1.
else dp[i]=q[f]+1;
}
//for(int i=0;i<=L;i+=2)printf("%d ",dp[i]==oo?-1:dp[i]);puts("");
printf("%d\n",dp[L]==oo?-1:dp[L]); return 0;
}
POJ 2373的更多相关文章
- POJ 2373 Dividing the Path(DP + 单调队列)
POJ 2373 Dividing the Path 描述 农夫约翰的牛发现,在他的田里沿着山脊生长的三叶草是特别好的.为了给三叶草浇水,农夫约翰在山脊上安装了喷水器. 为了使安装更容易,每个喷头必须 ...
- [POJ 2373][BZOJ 1986] Dividing the Path
Link: POJ 2373 传送门 Solution: 一开始想错方向的一道简单$dp$,不应该啊…… 我一开始的想法是以$cows' ranges$的节点为状态来$dp$ 但明显一个灌溉的区间的两 ...
- poj 2373 Dividing the Path
Dividing the Path Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2858 Accepted: 1064 ...
- poj 2373 单调队列优化背包
思路:我们用单调队列保存2*b<=i-j<=2*a中的最大值.那么队列头就是最大值,如果队头的标号小于i-2*b的话,就出队,后面的肯定用不到它了. #include<iostrea ...
- POJ 2373 Yogurt factory
简单DP. 这周所用的实际花费是上一周的花费+S与这周费用的较小值. #include<cstdio> #include<cstring> #include<cmath& ...
- 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 ...
- POJ 2373 单调队列优化DP
题意: 思路: f[i] = min(f[j]) + 1; 2 * a <= i - j <= 2 *b: i表示当前在第i个点.f[i]表示当前最少的线段个数 先是N^2的朴素DP(果断 ...
随机推荐
- vs2008bin下Debug bll Release文件 obj下的Debug bll Release文件区别
Bin目录用来存放编译的结果,bin是二进制binrary的英文缩写,因为最初C编译的程序文件都是二进制文件,它有Debug和Release两个版本,分别对应的文件夹为bin/Debug和bin/Re ...
- easyui验证提示框 卡在屏幕上!!
场景:验证提示框,关闭diglog窗口后 还显示在页面中 解决方法: 在窗口关闭事件中,删除提示框(这貌似并不可行),只能将验证提示框隐藏起来. $('#dialog').dialog({ onClo ...
- 删除django
1.命令行运行python 2.import django3.print(django.__path__)4.删除django目录即可
- 使用T-sql建库建表建约束
为什么要使用sql语句建库建表? 现在假设这样一个场景,公司的项目经过测试没问题后需要在客户的实际环境中进行演示,那就需要对数据进行移植,现在问题来了:客户的数据库版本和公司开发阶段使用的数据库不兼容 ...
- 【PostgreSQL-9.6.3】函数(3)--日期和时间函数
在PostgreSQL中,DATE.TIME.TIMESTAMP是三种不同的数据类型.DATE表示日期类型,格式为YYYY-MM-DD或YYYYMMDD:TIME表示时间类型,格式为hh:mi:ss: ...
- 图方法:寻找无向图联通子集的JAVA版本
图像处理中一般使用稠密方法,即对图像进行像素集合进行处理.在图像拓扑方面,更多地应用图计算方法. 寻找无向图联通子集的JAVA版本,代码: //查找无向图的所有连通子集//wishchin!!! pu ...
- 读书笔记「Python编程:从入门到实践」_4.操作列表
4.1 遍历整个列表 4.1.1 深入地研究循环 4.1.2 在for循环中执行更多的操作 4.1.3 在for循环结束后执行一些操作 例 magicians = ['alice', ' ...
- Model2
Model1: Model2:
- webpack学习(六)—webpack+react+es6(第3篇)
接上篇 : webpack学习(六)—webpack+react+es6(第2篇) 上篇其实是有问题的,问题在取服务器数据这块.this.props 表示那些一旦定义,就不再改变的特性,而 this. ...
- webpack学习(四)— webpack-dev-server
webpack提供给我们检查压缩代码的功能之外,还提供了1个服务器的插件,这就是webpack-dev-server,利用这个差价我们可以启动个web服务器并时时更新我们的修改. 下面以1个简单的例子 ...