POJ 2373
2024-10-01 05:19:37
原本一道挺简单的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;
}
最新文章
- java生成验证码的逻辑
- 引用CSS文件到html网页里方法
- libvirt TLS
- java提高篇(三)-----理解java的三大特性之多态
- 我的前端故事----关于redux的一些思考
- Unity文档阅读 第二章 依赖注入
- 常见的java设计模式
- Android ScrollView和ListView滑动冲突解决记录
- spring boot (入门简介 demo)
- 在win10环境中安装xilinx vivado IDE时出现的问题及解决方法
- suse zypper 添加源
- 最全面的 Android 编码规范指南
- 历年至今TVB剧集目录(持续更新...我已看过的推荐)
- Python实现学生系统
- hdu 5111 树链剖分加函数式线段树
- LeetCode 47
- 笔记本制作centos qcow2格式文件
- Race to 1 UVA - 11762 (记忆dp概率)
- tomcat启动startup.bat一闪而过
- C语言关于指针的注意事项